標籤:
原文網址:http://blog.csdn.net/ueryueryuery/article/details/20607845
我寫了一個Dialog,Dialog中有一個ListView,想要點ListView中的一項後,跳轉到另外一個Activity去。
但在使用時,會偶爾報出下面的錯誤:
02-21 14:54:28.928: E/AndroidRuntime(2846): FATAL EXCEPTION: main
02-21 14:54:28.928: E/AndroidRuntime(2846): 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(2131165196, class android.widget.ListView) with Adapter(class com.jovision.multiscreen.views.DeviceScanSelectDialog$DeviceAdapter)]
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.widget.ListView.layoutChildren(ListView.java:1510)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.widget.AbsListView.onTouchModeChanged(AbsListView.java:2077)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver.java:591)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.view.ViewRoot.ensureTouchModeLocally(ViewRoot.java:2095)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.view.ViewRoot.performTraversals(ViewRoot.java:809)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.view.ViewRoot.handleMessage(ViewRoot.java:1861)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.os.Handler.dispatchMessage(Handler.java:99)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.os.Looper.loop(Looper.java:130)
02-21 14:54:28.928: E/AndroidRuntime(2846): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-21 14:54:28.928: E/AndroidRuntime(2846): at java.lang.reflect.Method.invokeNative(Native Method)
02-21 14:54:28.928: E/AndroidRuntime(2846): at java.lang.reflect.Method.invoke(Method.java:507)
02-21 14:54:28.928: E/AndroidRuntime(2846): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
02-21 14:54:28.928: E/AndroidRuntime(2846): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
02-21 14:54:28.928: E/AndroidRuntime(2846): at dalvik.system.NativeStart.main(Native Method)
其中錯誤描述:
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.
的意思大體是,你的adapter的內容變化了,但是你的ListView並不知情。請保證你adapter的資料在主線程中變更!
知道了原因,改起來就好辦多了,我將我的adapter類改為:
[java] view plaincopy
- private class DeviceAdapter extends BaseAdapter {
-
- private LayoutInflater inflater;
- private ArrayList<Device> devices;
-
- public DeviceAdapter() {
- inflater = LayoutInflater.from(mContext);
- }
-
- @SuppressWarnings("unchecked")
- public void setDeviceList(ArrayList<Device> list) {
- if (list != null) {
- devices = (ArrayList<Device>) list.clone();
- notifyDataSetChanged();
- }
- }
-
- public void clearDeviceList() {
- if (devices != null) {
- devices.clear();
- }
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return devices == null ? 0 : devices.size();
- }
- 以下略)
相對於原來,我做了兩項改動:
1.將所有資料“完全”儲存在adapter內部,即使有外部資料進入,也會用.clone()重建副本,保證了資料完全是由adapter維護的。
2.保證所有setDeviceList()/clearDeviceList()是從主線程裡調用的,如何保證是從主線程中調用的呢:
a.調用Activity.runOnUIThread()方法;
b.使用Handler(其實這並不非常準確,因為Handler也可以運行在非UI線程);
c.使用AsyncTask。
希望能幫到遇到同樣問題的同學~
【轉】解決java.lang.IllegalStateException: The content of the adapter has changed but ListView...的問題