對App進行開發測試時,偶爾出現app崩潰的問題。日誌以下:java
10-25 18:44:52.935 15290-15290/com.zzq.cnblogs E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.zzq.cnblogs, PID: 15290 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. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(16908298, class com.handmark.pulltorefresh.library.PullToRefreshListView$InternalListViewSDK9) with Adapter(class android.widget.HeaderViewListAdapter)] at android.widget.ListView.layoutChildren(ListView.java:1555) at android.widget.AbsListView.onLayout(AbsListView.java:2089) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1043) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14845) at android.view.ViewGroup.layout(ViewGroup.java:4631) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2026) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1783) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1039) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5648) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) at android.view.Choreographer.doCallbacks(Choreographer.java:574) at android.view.Choreographer.doFrame(Choreographer.java:544) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.j
其中android
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.
由異常的提示能夠看出,在一個後臺線程更新了UI界面,而UI界面必須由UI線程進行更新。然而,Android提供了幾種更新UI線程的方法。下面用Handler的方式更新UI,作個簡單的修改便可。更多關於UI線程更新的方法見:http://gqdy365.iteye.com/blog/2112471app
一、添加一個Handler屬性ide
private Handler handlerListView = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bundle bundle = (Bundle) msg.obj; int refreshType = (int) bundle.get("refreshType"); LinkedList<Article> list = (LinkedList<Article>) bundle.get("article"); for (Article article : list){ if (REFRESH_TYPE_UP == refreshType){ listData.add(article); }else if (REFRESH_TYPE_DOWN == refreshType){ listData.add(0, article); } } pullToRefreshView.onRefreshComplete(); adapter.notifyDataSetChanged(); } };
二、將直接更新UI內容的部分測試
pullToRefreshView.onRefreshComplete();
adapter.notifyDataSetChanged();
改爲spa
Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putInt("refreshType", refreshType); bundle.putSerializable("article", addList); msg.obj = bundle; handlerListView.sendMessage(msg);
將修改的數據發給handler去處理,而不是直接操做listview的adapter。線程
此外還能夠考慮使用activity的runOnUiThread方法進行更新。日誌