Android: IllegalStateException - 什么时候被抛出?

2022-09-04 06:37:20

在我的应用程序中,有时会引发以下异常:

07-28 14:49:25.398: ERROR/AndroidRuntime(8097):
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(2131099717, class android.widget.ListView) with
Adapter(class ch.uzh.csg.games4blue.gamebase.view.UserView$UserAdapter)]
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.ListView.layoutChildren(ListView.java:1432)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.AbsListView.onLayout(AbsListView.java:1113)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.onLayout(LinearLayout.java:918)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1108)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.onLayout(LinearLayout.java:920)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.FrameLayout.onLayout(FrameLayout.java:333)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.onLayout(LinearLayout.java:918)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.LinearLayout.onLayout(LinearLayout.java:918)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.FrameLayout.onLayout(FrameLayout.java:333)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.widget.FrameLayout.onLayout(FrameLayout.java:333)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.View.layout(View.java:6831)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.ViewRoot.performTraversals(ViewRoot.java:996)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.os.Handler.dispatchMessage(Handler.java:99)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.os.Looper.loop(Looper.java:123)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
android.app.ActivityThread.main(ActivityThread.java:4338)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
java.lang.reflect.Method.invokeNative(Native Method)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
java.lang.reflect.Method.invoke(Method.java:521)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):     at
dalvik.system.NativeStart.main(Native Method)

很难找到错误,因为在堆栈跟踪中,我的方法都没有列出。那么,有谁知道何时引发此异常?感谢您的任何提示。


答案 1

它确实告诉您发生错误的类:包含一个在其内部调用的类。ch.uzh.csg.games4blue.gamebase.view.UserViewUserAdapter

让我试着解释一下这里发生了什么 - 当你创建一个备份它时,通过向适配器请求它来获取它的数据。每次滚动时,ListView 都会要求适配器提供您滚动到的新项。ListViewAdapterListView

通常,您创建 ListView,创建适配器,在列表视图上设置适配器,然后就完成了。Android OS负责其余的工作。但是,您尝试执行的操作要复杂一些。您正在尝试偶尔更新适配器中的数据。您可以想象,如果适配器数据发生更改,则需要通知列表视图,对吗?如果要显示包含 2 个项目的列表,并且突然又向适配器添加 2 个项目,则该列表现在应显示 4 个项目!但是,如果列表视图必须不断检查以查看适配器是否已更改,那将是非常低效的,对吧?因此,需要做的是,listview 将假定适配器不会更改,并且适配器将在它发生更改时通知 listview。(列表视图和适配器之间的这种协议还具有其他好处,例如列表视图可以缓存从适配器检索到的某些项目以便快速访问。如果屏幕上显示 10 个列表项,则该列表实际上可能已经请求了 14 项。这样,如果您向上或向下滚动,则对于任一方向上的至少2个项目,ListView已经具有要显示的数据!

但是,您未能做到的是通知 listview 适配器内的数据已更改。在UserAdapter或UserView内部的某个地方,数据正在被更改!为了让每个人都能轻松做到这一点,也许你可以发布完整的UserView类?我敢打赌,你有一些数据对象,如ArrayList,作为UserView类中的私有变量。在 UserAdapter 类中,您将此数据提供给 ListView。但是,在 UserView 类中的某个位置,在将此数据集提供给 ListView 之后,您正在修改此数据集。

免责声明:我在这里主要复制其他答案,但我认为如果我将给出的2-3个答案结合起来,我可以更清楚地了解正在发生的事情

免责声明2:我累了,这似乎写得很差。让它成为一个wiki,希望有人清理我的深夜乱七八糟。如果这是完全无法理解的,就这么说,然后删除它


答案 2

您可以在堆栈跟踪中看到错误:

适配器的内容已更改,但 ListView 未收到通知。确保适配器的内容不是从后台线程修改的,而是仅从 UI 线程修改的。

您应该查看其中一个线程,并使其与 UI 线程同步。

在Android中做到这一点的方法是使用Handler。

http://developer.android.com/guide/appendix/faq/commontasks.html#threading