ListView数据源不同步问题The content of the adapter has changed but ListView did not receive a notification.

最近项目中出现了很多下面的异常:


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(16908298, class com.handmark.pulltorefresh.library.PullToRefreshListView$InternalListViewSDK9) with Adapter(class android.widget.HeaderViewListAdapter)]at android.widget.ListView.layoutChildren(ListView.java:1538)at android.widget.ListView.setSelectionInt(ListView.java:1955)at android.widget.AbsListView.resurrectSelection(AbsListView.java:5269)at android.widget.AbsListView.onWindowFocusChanged(AbsListView.java:2792)at android.view.View.dispatchWindowFocusChanged(View.java:7325)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:933)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:937)at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2890)at android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:137)at android.app.ActivityThread.main(ActivityThread.java:4745)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:511)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)at dalvik.system.NativeStart.main(Native Method)


追踪该异常,发现其源头都来自于ListView.layoutChildren()方法


ListView比较了mItemCount和Adapter的getCount,发现两者不相等,抛出异常

这个mItemCount就是ListView内部缓存的一个子条目的个数,adapter的getCount就是我们继承Adapter重写的方法,返回数据源的个数

所以我们就知道:

当listView的layout.layoutChildren()方法被调用时,其内部缓存的条目个数和我们的数据源数量不一致时,会抛出此异常

通俗点就是,数据源变化没有及时通知到ListView


接下来看下代码:


list.addAll(data);

hideWaiting();

adapter.setData(list);

adapter.notifyDataSetChanged();


很简单的代码,改变数据源,然后setData,然后notifyDataSetChanged

表面看起来没有任何问题,但是请注意,第二行数据源修改后调用了hideWaiting方法,隐藏Dialog

这个操作就有可能触发系统重绘界面,一直调用到layouChildren(),出现问题,抛出异常


那么layoutChildren()的调用时机呢?

当界面发生任何改变时,如创建销毁,输入法弹出隐藏,显示隐藏Dialog,都会调用到该方法

此方法是由系统调用的,充满了不确定性,所以尽量还是及时通知更新数据


总结:

使用Adapter一定要注意,修改数据源后及时通知更新,否则一旦系统因为某种原因重绘界面,就会出现问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值