在runOnUiThread里面更新adapter有BUG

SpreadService.getAdMsgList(id, pageNumber + "", new ChatCallBack() {

    @Override
    public void onSuccess(AppResult result) {
        List<DynamicdetailBean> list = JSONArray.parseArray(result
                .getData().toString(), DynamicdetailBean.class);
        if (list != null && list.size() > 0) {
            if (isFirstLoading) {
                datalist.clear();
                datalist.addAll(list);
            } else {
                datalist.addAll(list);
            }
        } 

//以上是oncreate()方法里面调用的方法,datalist也是在oncreate中初始化的集合,在service里面新建的一个工作线程执行http访问,成功后回调处理数据方法,具体太多,不列出,返回数据都正常,
//关键是下面的代码:

MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (isFirstLoading) { //是否第一次加载
isFirstLoading = false;
adapter = new ListAdapater(MainActivity.this,
1, datalist);
listView.setAdapter(adapter);
} else {
//TODO
adapter.notifyDataSetChanged();
}
footLoading.setVisibility(View.GONE);
isLoading = false;
}
});
//adapter是继承arrayadapter,就职声明了控件,每怎么重写方法,getview,class Viewholder什么的就不列出来了,如下:
private class ListAdapater extends ArrayAdapter {
private LayoutInflater inflater;
private SpannableStringBuilder builder;
private Context context;
private List list;

    // TODO
    public ListAdapater(Context context, int res,
            List<DynamicdetailBean> list) {
        super(context, res, list);
        this.inflater = LayoutInflater.from(context);
        this.context = context;
        this.list = list;
        builder = new SpannableStringBuilder("回复");
        ForegroundColorSpan yellowSpan = new ForegroundColorSpan(context
                .getResources().getColor(R.color.red_text));
        builder.setSpan(yellowSpan, 0, builder.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}   
但是每次从其他Activity跳转过来后,有时正常显示更新listview内容,有时就报错了:说listview没收到notification,如下:

但是如果不用runOnUiThread,改成用handler发消息就不会出错:
handler.sendMessage(handler.obtainMessage(1, datalist));
Handler handler = new Handler(){
    public void handleMessage(android.os.Message msg) {
        datalist = (List<DynamicdetailBean>) msg.obj;
        switch(msg.what){
        case 1:
            if (isFirstLoading) {
                isFirstLoading = false;
                adapter = new ListAdapater(OfficialActivity.this,
                        1, datalist);
                listView.setAdapter(adapter);
            } else {
                //TODO
                adapter.notifyDataSetChanged();
            }
            footLoading.setVisibility(View.GONE);
            isLoading = false;
            break;
        }
    };
};
这是为什么呢,runOnUiThread有限制条件么?还请各位大神指点啊!!!

4个回答

图片说明

以上为报错截图,说我没在主线程更新adapter,可ruOnUiThread就是在主线程更新的啊

adapter.notifydatasetchanged()前调用listview的requestLayout();

把 listview的adapter数据更新和dapter.notifyDataSetChanged()必须同时放到单独一个线程里,报错基本是都是这个原因,有人把adapter里的数据更新了,但是 dapter.notifyDataSetChanged() 放到一个单独线程去更新,结果出现notifyDataSetChanged更新同步的问题

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问