簡體   English   中英

Android:IllegalStateException-什么時候拋出?

[英]Android: IllegalStateException - When is it thrown?

在我的應用程序中,有時會引發以下異常:

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)

很難找到錯誤,因為在stacktrace中沒有列出我的方法。 那么,有人知道何時拋出該異常嗎? 感謝您的任何提示。

它確實告訴您錯誤發生在以下類別: ch.uzh.csg.games4blue.gamebase.view.UserViewch.uzh.csg.games4blue.gamebase.view.UserView包含一個名為UserAdapter的類。

讓我試着解釋這里發生了什么-當你創建一個ListViewAdapter進行備份時, ListView通過詢問適配器它得到它的數據。 每次滾動時,ListView都會向適配器詢問您滾動到的新項目。

通常,您創建ListView,創建適配器,在列表視圖上設置適配器,然后完成。 其余部分由Android OS負責。 但是,您嘗試執行的操作比較復雜。 您試圖偶爾更新適配器中的數據。 您可以想象如果適配器數據發生更改,則需要通知listview,對嗎? 如果您要顯示包含2個項目的列表,而您突然將另外2個項目添加到適配器,那么該列表現在應該顯示4個項目! 但是,如果必須不斷檢查listview以查看適配器是否已更改,那將是非常低效的,對嗎? 因此,需要做的是,列表視圖將假定適配器未更改,並且適配器將在更改時通知列表視圖。 (列表視圖和適配器之間的這種協議還帶來了其他好處,例如列表視圖可以緩存從適配器檢索到的某些項目以進行快速訪問。再者,如果屏幕上顯示了10個列表項目,則該列表可能實際上已經被請求了。 14個項目。這樣,如果您向上或向下滾動,則在任一方向上至少有2個項目,ListView已經具有要顯示的數據!)

但是,您做不到的是通知列表視圖適配器內部的數據已更改。 在UserAdapter或UserView內部的某個位置,數據正在更改! 為了使每個人都容易做到這一點,也許您可​​以發布完整的UserView類? 我敢打賭,您有一些數據對象(例如ArrayList)作為UserView類內部的私有變量。 在UserAdapter類內部,您正在將此數據提供給ListView。 但是,在將UserData類提供給ListView 之后 ,您正在修改該數據集。

免責聲明:我主要是在這里復制其他答案,但是我認為,如果我結合給出的2-3個答案,可以更清楚地了解正在發生的情況

免責聲明2:我很累,這似乎寫得不好。 使其成為Wiki,希望有人能清理我的深夜混亂。 如果這完全無法理解,請說出並刪除它

您可以在stacktrace中看到錯誤:

適配器的內容已更改,但ListView沒有收到通知。 確保不從后台線程修改適配器的內容,而僅從UI線程修改。

您應該調查一個線程,並使其與UI線程同步。

在Android中執行此操作的方法是使用Handler。

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

使用ch.uzh.csg.games4blue.gamebase.view.UserView$UserAdapter

確實,當您修改適配器的內容時​​,在沒有通知您的列表視圖或使用適配器的任何其他視圖通知其內容應該更新的情況下,會發送此類錯誤。
嘗試在適配器上調用.notifyDataSetChanged()

我遇到了與我使用asynchrousTask填充listview中的數據時遇到的相同問題,我通過重寫更新fn中的Ui的代碼解決了

  1. onPostExecute()
  2. onPreExecute()

因為這些功能在UI線程中運行。

希望這可以幫助。

我剛剛解決了這個問題!

以前,我像這樣進行繁重的處理,其中list是靜態的,並且在Activity類下:

@Override
protected Void doInBackground(Void... arg0) {
    for (int i=0; i<bigChunk.size(); i++) {
        list.add(somethingHeavy(i));
    }
}

然后,我創建了一個新列表,並將其添加到:

List<YourObject> listToAdd;
@Override
protected Void doInBackground(Void... arg0) {
    listToAdd = new ArrayList<YourObject>();
    for (int i=0; i<bigChunk.size(); i++) {
        listToAdd.add(somethingHeavy(i));
    }
}
@Override
protected void onPostExecute(Void result) {
    list = listToAdd;
    adapter.notifyDataSetChanged();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM