Android アプリケーション用の XMPP クライアントを実装しています。私に送信されたチャット メッセージを取得するために、Smack の PacketListener を使用しています。アプリケーションの XMPP 部分では、すべて正常に動作します。メッセージを送受信できます。しかし、受信したメッセージの表示に問題があります。
メッセージを表示するために、アプリケーションはメッセージを ListView にバインドする ArrayAdapter を使用します。私が送信したメッセージは問題なく表示されるため、アダプタ自体は正常に動作します。しかし、受信したメッセージはそうではありません。UI との対話が発生した場合にのみ表示されます。どうやら、これはスレッドの問題です。
Javadoc とデバッガーが教えてくれたことに間違いがなければ、PacketListener.processPacket() メソッドは独自のスレッドで実行され、ListView の更新は、ハンドラーが次に行うべきことがあり、したがって処理する場合にのみ実行されます。それ。私の質問は、ハンドラーにすぐに処理するように指示するにはどうすればよいですか? ここで、このワーカー スレッドとメイン スレッド間の通信はどのように機能するのでしょうか? Runnable を自分で作成していないため、これを処理する方法がわかりません。
コードは次のとおりです。
public class Chat extends Activity {
private ArrayList<String> mMessages;
private ArrayAdapter<String> mAdapter;
private ListView mMessageListView;
private EditText mInput;
private String mRecipient;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
Bundle extras = getIntent().getExtras();
mRecipient = extras.getString("jabberid");
mMessages = new ArrayList<String>();
mMessageListView = (ListView) findViewById(R.id.chatMessageList);
mInput = (EditText) findViewById(R.id.chatInput);
mAdapter = new ArrayAdapter<String>(this, R.layout.channelentry, mMessages);
mAdapter.notifyDataSetChanged();
mMessageListView.setAdapter(mAdapter);
// Getting messages
PacketFilter packetFilter = new MessageTypeFilter(Message.Type.chat);
// XMPPConnection already connected and authenticated
XmppManager.connection.addPacketListener(new PacketListener() {
// Here is where it doesn't display the received message
@Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
displayMessage(message);
}
}, packetFilter);
// Sending messages
Button send = (Button) findViewById(R.id.chatSend);
send.setOnClickListener(new View.OnClickListener() {
// Here everything works just fine
@Override
public void onClick(View v) {
Message message = new Message(mRecipient, Message.Type.chat);
message.setBody(mInput.getText().toString());
XmppManager.connection.sendPacket(message);
displayMessage(message);
}
});
}
private void displayMessage(Message message) {
String sender = message.getFrom();
String chat = sender + " > " + message.getBody();
mAdapter.add(chat);
mAdapter.notifyDataSetChanged();
}
}