Android在多次调用的线程上运行

时间:2013-04-20 11:51:26

标签: android android-arrayadapter asmack android-handler

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

        }
    }
}

1 个答案:

答案 0 :(得分:2)

请勿直接致电handleMessage

messageHandler.handleMessage(aosMessage);

您应该从邮件中的给定HandlersetTarget(Handler handler)获取邮件,然后在邮件上调用sendToTarget()以使其由{{1}发送和处理}。如果您正确实施Handler,则不需要Handler