android下拉列表偶尔出现崩溃,查看日志打印错误为:
12-28 14:17:35.772: E/AndroidRuntime(9922):
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131034452, class custom_refreshview.ListViewFrame) with Adapter(class android.widget.HeaderViewListAdapter)]
相关使用代码:
public class ScalingAuditingMainActivity extends FragmentActivity implements IXListViewListener { ScalingAuditingAdapter mScalingAuditingAdapter; private ListtotaiList = new ArrayList (); private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case SETDATA: mScalingAuditingAdapter.notifyDataSetChanged(); mBegin = "0"; break; case ERROR: break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scaling_auditing_main); } @Override protected void onResume() { boolean netOK = isNetOK(ScalingAuditingMainActivity.this); if (netOK) { // 网络状态良好,显示加载对话框 initView(); } else { // 网络状态错误,不显示加载对话框 } super.onResume(); } private void initView() { pullToRefreshListView_fragmentvp_info = (ListViewFrame) findViewById(R.id.scaling_auditing_pullToRefreshListView_fragmentvp); mScalingAuditingAdapter = new ScalingAuditingAdapter(totaiList, ScalingAuditingMainActivity.this); if (mScalingAuditingAdapter != null) { Log.e("****11", "****11"); pullToRefreshListView_fragmentvp_info .setAdapter(mScalingAuditingAdapter); } else { Log.e("te****", "te****"); } pullToRefreshListView_fragmentvp_info.setPullLoadEnable(true); pullToRefreshListView_fragmentvp_info.setXListViewListener(this); pullToRefreshListView_fragmentvp_info .setOnItemClickListener(new Listener()); } private void onLoad() { pullToRefreshListView_fragmentvp_info.stopRefresh(); pullToRefreshListView_fragmentvp_info.stopLoadMore(); } @Override public void onRefresh() {// 下拉刷新 handler.postDelayed(new Runnable() { @Override public void run() { start = refreshCnt; totaiList.clear(); inJsonData("0"); onLoad(); } }, 2000); } @Override public void onLoadMore() {// 上拉加载 handler.postDelayed(new Runnable() { @Override public void run() { k += Integer.parseInt(curCount); if (k >= Integer.parseInt(totalCount)) { Toast.makeText(ScalingAuditingMainActivity.this, R.string.listview_header_hint_end, Toast.LENGTH_SHORT).show(); } else { mBegin = k + ""; inJsonData(mBegin); } onLoad(); } }, 2000); } public void inJsonData(final String start) { new Thread() { public void run() { totaiList.clear(); handler.sendEmptyMessage(SETDATA); // 网络请求完之后,加入scalingAuditingEntity // 然后加入list totaiList.add(scalingAuditingEntity); handler.sendEmptyMessage(SETDATA); } }.start(); } }
意思就是adapter的内容变化了,但是ListView并不知情。检查一下是否在新线程改变了传入的数据,而没有通知listview.最好贴点代码出来
问题就在inJsonData里面,totailist在网络线程改变了,虽然发送message通知listview更新,但是两个线程间同步存在时间差,使得adapter和listview的数据不一致。解决方法就是把totaiList.clear();totaiList.add(scalingAuditingEntity);放到UI线程中做。