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






本文转自秋楓博客园博客,原文链接:http://www.cnblogs.com/rwxwsblog/p/4910575.html,如需转载请自行联系原作者
目录
相关文章
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
670 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
309 0
|
11月前
|
存储 消息中间件 人工智能
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
618 4
|
11月前
|
存储 开发者 容器
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
本文介绍了ArkTS语言中的Class类、泛型、接口、模块化、自定义组件及状态管理等核心概念,并结合代码示例讲解了对象属性、构造方法、继承、静态成员、访问修饰符等内容,同时涵盖了路由管理、生命周期和Stage模型等应用开发关键知识点。
704 1
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1534 4
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
731 11
移动端数据抓取:Android App的TLS流量解密方案
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
717 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
746 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
Android开发
Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作
前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行。         比如,一个加载网络图片的的方法,需要在子线程中执行。 /** * 加载网络图片 */ private void loadImage() { ...
1467 0
|
10月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1784 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡