我正在尝试使用 aSmack 实现 MUC,但似乎无法使用 ArrayAdapter 正确更新 UI。我已经在我的ChatService.java中设置了我的监听器,如下所示:
connection.addPacketListener(new MessageListener(), new PacketFilter() {
public boolean accept(Packet packet) {
Message msg = (Message) packet;
return msg.getBody() != null;
}});
我的侦听器类如下所示:
private class MessageListener implements PacketListener {
/**
* Constructor.
*/
public MessageListener() {
}
public void processPacket(Packet packet) {
if(packet instanceof Message ) {
Message message = (Message) packet;
android.os.Message aosMessage = new android.os.Message();
aosMessage.what = message.getType().ordinal();
aosMessage.obj = message;
messageHandler.handleMessage(aosMessage);
}
}
}
现在问题如下;首先,我尝试通过处理程序更新 UI(处理程序在我的ChatActivity.java中定义):
private final Handler messageHandler = new Handler() {
private Message chatMessage;
@Override
public void handleMessage(final android.os.Message msg) {
chatMessage = (Message) msg.obj;
if(Message.Type.values()[msg.what].equals(Message.Type.groupchat)) {
conversationArrayAdapter.add("Received group message: " + chatMessage.getBody());
} else if (Message.Type.values()[msg.what].equals(Message.Type.chat)) {
conversationArrayAdapter.add("Received private message: " + chatMessage.getBody());
}
}
};
但这不会更新 UI,直到从用户端引入交互。经过一点网络挖掘后,我意识到我需要使用 post(或 runonUIthread)方法来实现这一点,所以我尝试了:
private final Handler messageHandler = new Handler() {
private Message chatMessage;
@Override
public void handleMessage(final android.os.Message msg) {
chatMessage = (Message) msg.obj;
this.post(new Runnable() {
public void run() {
if(Message.Type.values()[msg.what].equals(Message.Type.groupchat)) {
conversationArrayAdapter.add("Received group message: " + chatMessage.getBody());
conversationArrayAdapter.notifyDataSetChanged();
} else if (Message.Type.values()[msg.what].equals(Message.Type.chat)) {
conversationArrayAdapter.add("Received private message: " + chatMessage.getBody());
conversationArrayAdapter.notifyDataSetChanged();
}
}
});
}
};
但是现在 run() 方法被多次调用(在调试时确认),并且 UI 更新为看似随机数量的相同消息(每条消息的重复数量不同,但显示了所有消息)。
这是我的第一个 android 应用程序(但我是一名 java 开发人员),我很确定我在这里的架构做错了什么。任何帮助(最好是详细的 - 带有代码示例和/或对文档正确区域的引用)将不胜感激。
提前致谢!
在@Emil 的回答之后更正了工作片段
private class MessageListener implements PacketListener {
/**
* Constructor.
*/
public MessageListener() {
}
public void processPacket(Packet packet) {
if(packet instanceof Message ) {
Message message = (Message) packet;
android.os.Message aosMessage = new android.os.Message();
aosMessage.what = message.getType().ordinal();
aosMessage.obj = message;
aosMessage.setTarget(messageHandler);
aosMessage.sendToTarget();
}
}
}