1

我正在尝试使用 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();

        }
    }
}
4

1 回答 1

2

不要handleMessage直接打电话:

messageHandler.handleMessage(aosMessage);

您应该从给定的消息Handler或消息中获取setTarget(Handler handler)消息,然后调用sendToTarget()该消息以使其由Handler. 如果您Handler正确实施,则不需要post为此。

于 2013-04-20T11:57:30.453 回答