Android 애플리케이션 용 XMPP 클라이언트를 구현 중입니다. 나에게 보낸 채팅 메시지를 얻으려면 Smack에서 PacketListener를 사용하고있다. 응용 프로그램의 XMPP 부분을 사용하면 모든 것이 잘 동작합니다. 나는 메시지를 보내고받을 수있다. 하지만받은 메시지를 표시하는 데 문제가 있습니다.Android : PacketListener 작업자 스레드에서 ArrayAdapter/ListView 업데이트
메시지를 표시하기 위해 내 응용 프로그램은 ListAdapter에 바인딩하는 ArrayAdapter를 사용합니다. 어댑터 자체는 문제없이 전송 한 메시지를 표시하므로 정상적으로 작동합니다. 하지만받은 메시지에는 그렇지 않습니다. UI와의 상호 작용이 발생하는 경우에만 표시됩니다. 분명히 이것은 스레딩 문제입니다.
Javadoc과 디버거에서 나에게 말한 것과 틀린 부분이 없다면 PacketListener.processPacket() 메서드는 자체 스레드에서 실행되고 Handler에 다음 작업이있는 경우에만 ListView 업데이트가 실행됩니다. 그렇게하고 처리한다. 내 질문은 지금, 처리기 즉시 처리하도록 어떻게 말할 수 있습니까? 이 작업자 스레드와 기본 스레드 간의 통신은 어떻게 작동합니까? Runnable을 직접 만들지 않았으므로 어떻게 처리해야할지 모르겠다. 당신이 당신의 UI 스레드 내에서 Handler
를 만들 경우 당신이 당신의 displayMessage()
방법을 호출하는 Runnable
인수로에 post()
를 호출 할 수
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();
}
}