您的位置:首页 > 其它

(ListView使用错误)The content of the adapter has changed but ListView did not receive anotification

2016-11-20 21:23 567 查看
我犯过的错误:分享一下解决办法原文:http://bbs.51cto.com/thread-1132843-1-1.html一问题引出在修改bug的过程中,看到一个bug;里面的异常日志是:java.lang.IllegalStateException:ThecontentoftheadapterhaschangedbutListViewdidnotreceiveanotification.Makesurethecontentofyouradapterisnotmodifiedfromabackgroundthread,butonlyfromtheUIthread.MakesureyouradaptercallsnotifyDataSetChanged()whenitscontentchanges.[inListView(2131296454,classcom.android.contacts.widget.AutoScrollListView)withAdapter(classcom.android.contacts.group.GroupBrowseListAdapter)]atandroid.widget.ListView.layoutChildren(ListView.java:1555)atcom.android.contacts.widget.AutoScrollListView.layoutChildren(AutoScrollListView.java:74)atandroid.widget.ListView.setSelectionInt(ListView.java:1987)atandroid.widget.AbsListView.resurrectSelection(AbsListView.java:5512)atandroid.widget.AbsListView.onWindowFocusChanged(AbsListView.java:2858)atandroid.view.View.dispatchWindowFocusChanged(View.java:7900)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:968)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:972)atandroid.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3149)atandroid.os.Handler.dispatchMessage(Handler.java:102)atandroid.os.Looper.loop(Looper.java:136)atandroid.app.ActivityThread.main(ActivityThread.java:5120)atjava.lang.reflect.Method.invokeNative(NativeMethod)atjava.lang.reflect.Method.invoke(Method.java:515)atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:818)atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)atdalvik.system.NativeStart.main(NativeMethod)二分析过程简单来看的话,是一个IllegalStateException,从ListView1555行抛出来的。
01
//
Handletheemptysetbyremovingallviewsthatarevisible
02
03
//
andcallingitaday
04
05
if
(mItemCount==
0
)
{
06
07
resetList();
08
09
invokeOnItemScrollListener();
10
11
return
;
12
13
}
else
if
(mItemCount!=mAdapter.getCount()){
14
15
throw
new
IllegalStateException(
"Thecontentoftheadapterhaschangedbut"
16
17
+
"ListViewdidnotreceiveanotification.Makesurethecontentof"
18
19
+
"youradapterisnotmodifiedfromabackgroundthread,butonlyfrom"
20
21
+
"theUIthread.MakesureyouradaptercallsnotifyDataSetChanged()"
22
23
+
"whenitscontentchanges.[inListView("
+getId()+
","
+getClass()
24
25
+
")withAdapter("
+mAdapter.getClass()+
")]"
);
26
27
}
找到这行代码也就是说当mItemCount!=mAdapter.getCount()的时候会抛出这个异常。那么思考两个问题1.mItemCount什么时候赋值?2.mAdapter.getCount()又是什么呢?先分析第2点,mAdapter.getCount(),因为这相对比较简单,大家也比较熟悉。没错,就是我们自定义Adapter的时候,重写的getCount()的方法。类似于这种写法
01
public
class
GroupBrowseListAdapter
extends
BaseAdapter{
02
03
...
04
05
PrivateList<String>mdata;
06
07
public
int
getCount(){
08
09
return
mdata.size();
10
11
}
12
13
...
14
15
}
一般返回就是要显示集合(list,cursor,数组)之类的大小,也就是你listview的Item总数目那么来分析第1点,mItemCount是什么赋值的呢?首先,找到它定义的地方文件路径:frameworks\base\core\java\android\widget\AdapterView.java代码:
1
/**
2
3
*Thenumberofitemsinthecurrentadapter.
4
5
*/
6
7
@ViewDebug
.ExportedProperty(category=
"list"
)
8
9
int
mItemCount;
赋值的地方1.ListView.setAdapter
01
public
void
setAdapter(ListAdapteradapter){
02
03
...
04
05
if
(mAdapter!=
null
)
{
06
07
mAreAllItemsSelectable=mAdapter.areAllItemsEnabled();
08
09
mOldItemCount=mItemCount;
10
11
mItemCount=mAdapter.getCount();
12
13
...
14
15
}
16
17
...
18
19
}
2.frameworks\base\core\java\android\widget\AdapterView.java
01
class
AdapterDataSetObserver
extends
DataSetObserver{
02
03
private
ParcelablemInstanceState=
null
;
04
05
<ahref=
"http://home.51cto.com/index.php?s=/space/5017954"
target=
"_blank"
>
@override
</a>
06
07
public
void
onChanged(){
08
09
mDataChanged=
true
;
10
11
mOldItemCount=mItemCount;
12
13
mItemCount=getAdapter().getCount();
14
15
....
16
17
}
上面是两处给mItemCount赋值的地方第1个是给ListView设置adapter的时候,第2个调用adapter.notifyDataSetChanged()的时候调用那么解决这个问题就很简单了,就是你的数据集变化的时候(这个时候getCount()返回值就会变化),调用adapter.notifyDataSetChanged()通知adapter去更新mItemCount。三结论当你的数据集发生变化的时候,比如重新查询,不要忘记调用adapter.notifyDataSetChanged();当然不止你的数据集发生变化,任何会导致你的adapter.getCount()方法返回值发生变化的情况发生时,都应该调用adapter.notifyDataSetChanged()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐