Original URL: http://www.cnblogs.com/monodin/p/3874147.html
1, problem description
1 07-28 17:22:02.162:e/androidruntime (16779): Java.lang.IllegalStateException:The content of the adapter has changed BU The T ListView does not receive a notification. Make sure the content of your adapter are not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifydatasetchanged () while its content changes. [In the ListView (2131034604, Class Android.widget.ListView) with Adapter (class Com.nodin.sarah.HeartListAdapter)] 2 3 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.ListView.layoutChildren (listview.java:1555) 4 5 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.AbsListView.onLayout (abslistview.java:2091) 6 7 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.View.layout (view.java:14785) 8 9 07-28 17:22:02.162:e/androidr Untime (16779): at Android.view.ViewGroup.layout (viewgroup.java:4631) ten 07-28 17:22:02.162:e/androidruntime (16779 ): At Android.widget.RelativeLayout.onLayout (relativelayout.java:1055) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.View.layout (view.java:14785) 14 15 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.ViewGroup.layout (viewgroup.java:4631) 16 17 07-28 17:22:02.162 : E/androidruntime (16779): at Android.widget.FrameLayout.layoutChildren (framelayout.java:453) 18 19 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.FrameLayout.onLayout (framelayout.java:388) 20 21 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.View.layout (view.java:14785), 07-28 17:22:02.162:e/ Androidruntime (16779): at Android.view.ViewGroup.layout (viewgroup.java:4631) 07-28 17:22:02.162:e/ Androidruntime (16779): at Android.support.v4.view.ViewPager.onLayout (viewpager.java:1589) 07-28 17:22:02.162:e /androidruntime (16779): at Android.view.View.layout (view.java:14785) 07-28 17:22:02.162:e/androidruntime (16779 ): At Android.view.ViewGroup.layout (viewgroup.java:4631) 07-28 17:22:02.162:e/Androidruntime (16779): at Android.widget.RelativeLayout.onLayout (relativelayout.java:1055) 32 33 07-28 17:22:02.162: E/androidruntime (16779): at Android.view.View.layout (view.java:14785) 07-28 17:22:02.162:e/androidruntime ( 16779): At Android.view.ViewGroup.layout (viewgroup.java:4631), 07-28 17:22:02.162:e/androidruntime (16779): At and Roid.widget.FrameLayout.layoutChildren (framelayout.java:453) 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.FrameLayout.onLayout (framelayout.java:388) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.View.layout (view.java:14785) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.ViewGroup.layout (viewgroup.java:4631) 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.LinearLayout.setChildFrame (linearlayout.java:1671) 07-28 17:22:02.162:e/androidruntime (16779) : At Android.widget.LinearLayout.layoutVertical (linearlayout.java:1525) 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.LinearLayout.onLayout (linearlayout.java:1434), 07-28 17:22:02.162:e/ Androidruntime (16779): at Android.view.View.layout (view.java:14785), 07-28 17:22:02.162:e/androidruntime (16779) : At Android.view.ViewGroup.layout (viewgroup.java:4631), 07-28 17:22:02.162:e/androidruntime (16779): at ANDROID.W Idget. Framelayout.layoutchildren (framelayout.java:453) 07-28 17:22:02.162:e/androidruntime (16779): at Android.widget.FrameLayout.onLayout (framelayout.java:388) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.View.layout (view.java:14785) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.ViewGroup.layout (viewgroup.java:4631) 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.ViewRootImpl.performLayout (viewrootimpl.java:1985) 07-28 17:22:02.162:e/androidruntime (16779): At Android.view.ViewRootImpl.performTraversals (viewrootimpl.java:1742), 07-28 17:22:02.162:e/andRoidruntime (16779): at Android.view.ViewRootImpl.doTraversal (viewrootimpl.java:998), 07-28 17:22:02.162:e/ Androidruntime (16779): at Android.view.viewrootimpl$traversalrunnable.run (viewrootimpl.java:5582) 70 71 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.choreographer$callbackrecord.run (Choreographer.java:749) 72 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.Choreographer.doCallbacks (choreographer.java:562) 74 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.Choreographer.doFrame (choreographer.java:532) 76 77 07-28 17:22:02.162:e/androidruntime (16779): at Android.view.choreographer$framedisplayeventreceiver.run ( choreographer.java:735) 07-28 17:22:02.162:e/androidruntime (16779): at Android.os.Handler.handleCallback ( handler.java:733) 07-28 17:22:02.162:e/androidruntime (16779): at Android.os.Handler.dispatchMessage ( handler.java:95) 07-28 17:22:02.162:e/androidruntime (16779): at Android.os.Looper.loop (Looper.java:137) 07-28 17:22:02.162:e/androidruntime (16779): at Android.app.ActivityThread.main ( activitythread.java:4998) 07-28 17:22:02.162:e/androidruntime (16779): at java.lang.reflect.Method.invokeNative (Native Method) 07-28 17:22:02.162:e/androidruntime (16779): at Java.lang.reflect.Method.invoke (method.java:515) 07-28 17:22:02.162:e/androidruntime (16779): at Com.android.internal.os.zygoteinit$methodandargscaller.run ( zygoteinit.java:777) 07-28 17:22:02.162:e/androidruntime (16779): at Com.android.internal.os.ZygoteInit.main ( zygoteinit.java:593) 94 07-28 17:22:02.162:e/androidruntime (16779): at Dalvik.system.NativeStart.main (Native Method) 07-28 17:22:02.162:w/activitymanager (588): Force finishing activity
2, the recurrence scene uses the ListView and the adapter realizes the dynamic deletion data list function, the initialization data divides into two parts: The local and the network. So when the adapter data is initialized, the local data is added to the container first. At the same time, the network request is initiated, and then appended to the container when loading is complete. The problem is: when appending data after the network request is complete, throw the above exception. 3. Cause analysis
Exception Interpretation:
adapter's data content has changed, but the ListView has not received a notification. To ensure that the adapter data content is not modified in the background thread, modify it in the UI thread. Make sure to call the Notifydatasetchanged () method when the adapter data content changes. and regardless of exception content, first check the Android source code to see where the exception is thrown out. The Layoutchildren () method in the ListView has the following method:
1//Handle The empty set by removing all views that is visible 2//And calling it a Day 3 if (Mitemcount = = 0) {4 Resetlist (); 5 Invokeonitemscrolllistener (); 6 return; 7} else if (mitemcount! = Madapter.getcount ()) {8 throw new Illega Lstateexception ("The content of the adapter has changed but" 9 + "ListView does not receive a notification. Make sure the content of "Ten +" Your adapter is not modified from a background thread, and only "one +" from the UI Thread. [In the ListView ("+ getId () +", "+ getclass () +") with Adapter ("+ madapter.getclass () +")] "); 13}
i.e.
This exception is thrown when the data count in the ListView cache is not equal to Adapter.getcount () in the ListView. Combined with the beginning of the anomaly interpretation, it can be concluded that the adapter data dynamic update problem. Double-Check Your code:
when the network request is complete, the new custom method AddData (list) Update data in adapter is called directly on the network thread (non-UI thread), and after the update has been updated in the AddData (list) method, Call adapter's notifydatasetchanged () method to notify the update by handler the policy that sent the message.
as a result, it is not guaranteed that the adapter data is updated immediately when calling Notifydatasetchanged () to notify the ListView that the time difference between the two threads causes the data to be out of sync, causing the ListView to Layoutchildren () when accessing adapter's GetCount () method, adapter is already the latest data source, and the cached data count in the ListView is still the count of the old data, and the final cause of the problem finally surfaced. 4. Solution in this case, the solution is:
The adddata (List) method to update the code of the data, and notifydatasetchanged () method is placed in the handler, to ensure that the data update timely notify the ListView. In order to avoid this problem as much as possible, later programming tries to check its own code from the following aspects:
- Make sure to call the Notifydatasetchanged () method to notify the ListView when the adapter data is updated
- Data updates and notifydatasetchanged () are placed within the UI thread and must be executed in a synchronous sequence, not asynchronously
- Double check to make sure the GetCount () method returns the correct value
"Turn" about adapter the content of the adapter has changed problem analysis about adapter The content of the adapter has changed problem analysis