zoukankan      html  css  js  c++  java
  • Android app主线程UI更新间歇性崩溃的问题

      对App进行开发测试时,偶尔出现app崩溃的问题。日志如下:

    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

      其中

    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/2112471

      1、添加一个Handler属性

        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();
            }
        };

      2、将直接更新UI内容的部分

      pullToRefreshView.onRefreshComplete();
      adapter.notifyDataSetChanged();

      改成

        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方法进行更新。

  • 相关阅读:
    记一次失败的发布经历
    使用Test Director 编写测试用例的一点经验
    Windows Embedded 7 Standard 裁剪过程图解教程
    人生中第一次刮餐饮发票中奖5块!
    Proj EULibHarn Paper Reading: IntelliGen: Automatic Driver Synthesis for FuzzTesting
    Proj EULibHarn Paper Reading: FuzzGen: Automatic Fuzzer Generation
    Proj THUDBFuzz Paper Reading: Lenient Execution of C on a Java Virtual Machine
    Proj AutoWriter Paper Reading: Abstract Syntax Networks for Code Generation and Semantic Parsing
    Proj THUDBFuzz Paper Reading: ContextAware FailureOblivious Computing as a Means of Preventing Buffer Overflows
    Proj EULibHarn Paper Reading: FUDGE: Fuzz Driver Generation at Scale
  • 原文地址:https://www.cnblogs.com/rwxwsblog/p/4910575.html
Copyright © 2011-2022 走看看