最近项目里要添加个聊天功能,我们使用的是环信SDK。
如果应用启动,不在聊天界面,接收到消息后就弹出通知栏消息通知用户,点击进入聊天界面。
如果用户已经在聊天界面,就要将接收到的数据添加到adapter里,动态显示消息。
问题卡在,接收到消息后调用更新界面回调,给adapter里add新数据,然后调用adapter.notifyDataSetChanged()。
结果数据并没有刷新!
查看log,调用notifyDataSetChanged()后,onCreateViewHolder、onBindViewHolder方法并没有执行。
找了很久,最后在StackOverFlow上找到了答案,原文在这里
原来在我后台接收到数据调用更新界面回调方法时,其实和当前Activity不在同一个线程,我忙傻了把这点给忘了。
在回调里应该通过Handler发送数据到主线程,然后再给adapter里填数据,调用notifyDataSetChanged();
线程回调方法里:
Message handleMsg = new Message();
Bundle bundle = new Bundle();
bundle.putParcelable("1",message);
handleMsg.setData(bundle);
handleMsg.what = 1;
updateChatHandler.sendMessage(handleMsg);
处理消息的Handler:
Handler updateChatHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
EMMessage message = msg.getData().getParcelable("1");
// UIUtils.showToastSafe(WaitForChatActivity.this, "接收到消息的回调" + message.getBody());
setChatDataFromNet(message);
if (adapter != null) {
addData2Adapter(receiveMsg, false);
}
break;
}
super.handleMessage(msg);
}
};
更新数据时在主线程填数据,然后再调用RecyclerView.Adapter的 notifyDataSetChanged方法。
Android 开发过程中经常遇到更新界面没反应的情况,一开始我总是觉得自己代码这么完美!一定是数据或者编译器问题,结果一次次被打脸。T。T
今天总结下开发过程中遇到的几种更新 UI 没反应原因:
有时候服务端返回数据有误或者自己传递的数据为空,可以打个 Log 或者 跟个断点看看。
有时候在 请求接口回调、ListView 或者 RecyclerView 的 Adapter 里需要进行一些 UI 更新,这时不起作用的原因大多是因为我们在 子线程中更新UI。
子线程更新 UI 的方法有好多种,最终目的都是把消息发到主线程去操作:
写个 Handler 里进行 UI 操作,子线程 发送消息 在runOnUiThread中
Activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//do the ui-job
}
});
或者 post 到主线程
myView.post(new Runnable() {
@Override
public void run() {
//do the ui-job
}
})
3.方法调用错误
最常见的就是修改 ImageVIew 图片,应该调用
setImageResource 或者其他 setImageXXX 方法
而不是
setBackground 等 setBackgroundXXX 方法,后者只是修改背景,而不是图片本身。