我正在尝试使用asmack api开发一个Android聊天应用程序,服务器是openfire。 我处于处理来自用户的传入消息并代表它们相应的用户聊天屏幕(即活动)的阶段。
为此,我开发了两项活动,即
public class ResultActivity extends Activity
public class UserActivity extends Activity
resultactivity是一个维护名单存在信息的人,如在线,离开等等,所以这只是一个例子。
useractivity是与相应用户保持聊天列表的用户。此活动以ResultActivity中列表上的onclick事件开始。因此,根据结果活动中没有用户,这可以是多个。
因此,为了监听传入的数据包(即传入的消息),我在ResultActivity中添加了一个监听器,它将消息添加到全局arraylist中。
在结果活动中:
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
MainActivity.connection.addPacketListener(receive_message, filter);
PacketListener receive_message = new PacketListener() {
public void processPacket(Packet packet) {
message = (Message) packet;
String sender=null,body=null,sender_final=null;
if (message.getBody() !=null) {
Log.d("UA", "message from "+StringUtils.parseBareAddress(message.getFrom()));
Log.d("UA", "message is "+message.getBody());
sender = StringUtils.parseBareAddress(message.getFrom());
sender_final=sender.substring(0, sender.indexOf('@'));
body = message.getBody();
Log.d("UA", "Sender : "+sender_final+" body : "+body);
userMessage = new UserMessage("In", sender_final, body);
userMessage_list.add(userMessage);
userMessage_list.add(userMessage);
}
}
};
在全局消息列表中添加消息(即userMessage_list)后,我需要使用传入消息更新用户活动。 userMessage_list是在基本适配器扩展类的getview方法中用作数组的数组列表。
所以现在我需要使用notifydatasetchanged方法更新userActivity列表。
在UserActivity中:
private class UserActivityThread extends Thread {
@Override
public void run() {
UserActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
userAdapter.notifyDataSetChanged();
}
});
}
}
那么如何在另一个活动中调用notifydatasetchanged方法。
我很想知道如何在whatsapp或任何聊天应用程序中处理这种情况。
答案 0 :(得分:0)
我在聊天应用中使用ContentProvider
类和CursorLoader
解决了这个问题,每当某个URI有新记录时,它会自动得到通知。
在您的情况下,我建议您发布广播消息。包含ListView
消息的班级将注册BroadcastReceiver
,并且会收听可能的更新。每次在您的活动中触发BroadcastReceiver.onReceive
时,请刷新适配器。
希望有所帮助:)
修改强>
如何实现这一目标:
在您的活动中创建一个BroadcastReceiver
对象。
BroadcastReceiver mReceiver
;
编码您的广播接收器(例如,在您的onCreate上)
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String extra= intent.getStringExtra("extra");
Log.i("msg received: ", extra);
}
};
添加IntentFilter
(在您的onResume中可能有效)
IntentFilter intentFilter = new IntentFilter("com.myproject.myintentfilter");
4.1注册您的接收器
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerReceiver(mReceiver,intentFilter);
}
4.2取消注册您的接收器
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
this.unregisterReceiver(mReceiver);
}
sendBroadcast
与IntentFilter
匹配。最后:
Intent i = new Intent("com.myproject.myintentfilter").putExtra("extra", "This is a new value");
this.sendBroadcast(i);
编辑2
如果在您的活动轮换期间收到消息(接收者未注册),我找到了2个我不太满意的解决方案,但它们有效。
在方向更改后重新加载您的列表视图,因为活动会自行销毁,您只需重新加载列表视图的信息,无论如何都应该显示您的新消息。
在您的活动中放置一个静态字段,每次收到消息时,将此变量设置为TRUE。如果您的broadcastReceiver触发,将该变量置为false,并且在更改方向后调用onResume / onCreate
方法时,请检查静态变量并在变量为true时重新加载(重新加载ListView后将其置为false) )。