关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android中的ANR用法详解

    Android中的ANR用法详解

    2015-07-20 00:00:00 出处:工匠若水
    分享

    有过Android开发经历的人都不会对ANR陌生,它和崩溃一样是程序设计的问题。本文将以较为深入的视角来介绍什么是ANR,出现场景,如何避免以及如何定位分析ANR,希望可以帮助大家在编写程序时有所帮助。

    什么是ANR

    ANR全称Application Not Responding,意思就是程序未响应。假如一个应用无法响应用户的输入,系统就会弹出一个ANR对话框,如下图所示,用户可以自行选择继续等待亦或者是停止当前程序。

    说说Android中的ANR

    出现场景

    主线程被IO操作(从4.0之后网络IO不允许在主线程中)阻塞。 主线程中存在耗时的计算 主线程中错误的操作,比如Thread.wait或者Thread.sleep等

    Android系统会监控程序的响应状况,一旦出现下面两种情况,则弹出ANR对话框

    应用在 5秒 内未响应用户的输入事件(如按键或者触摸) BroadcastReceiver未在 10秒 内完成相关的处理

    如何避免

    基本的思路就是将IO操作在工作线程来处理,减少其他耗时操作和错误操作

    使用AsyncTask处理耗时IO操作。 使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。 使用Handler处理工作线程结果,而不是使用Thread.wait()或者Thread.sleep()来阻塞主线程。 Activity的onCreate和onResume回调中尽量避免耗时的代码 BroadcastReceiver中onReceive代码也要尽量减少耗时,建议使用IntentService处理。

    画龙点睛

    通常100到200毫秒就会让人察觉程序反应慢,为了更加提升响应,可以使用下面的几种方法

    假如程序正在后台处理用户的输入,建议使用让用户得知进度,比如使用ProgressBar控件。 程序启动时可以选择加上欢迎界面,避免让用户察觉卡顿。 使用Systrace和TraceView找出影响响应的问题。

    如何定位

    假如开发机器上出现问题,我们可以通过查看/data/anr/traces.txt即可,最新的ANR信息在最开始部分。我们从stacktrace中即可找到出问题的具体行数。本例中问题出现在MainActivity.java 27行,因为这里调用了Thread.sleep方法。

     root@htc_m8tl:/ # cat /data/anr/traces.txt | more
    
    ----- pid 30307 at 2015-05-30 14:51:14 -----
    Cmd line: com.example.androidyue.bitmapdemo
    
    JNI: CheckJNI is off; workarounds are off; pins=0; globals=272
    
    DALVIK THREADS:
    (mutexes: tll=0 tsl=0 tscl=0 ghl=0)
    
    "main" prio=5 tid=1 TIMED_WAIT
      | group="main" sCount=1 dsCount=0 obj=0x416eaf18 self=0x416d8650
      | sysTid=30307 nice=0 sched=0/0 cgrp=apps handle=1074565528
      | state=S schedstat=( 0 0 0 ) utm=5 stm=4 core=3
      at java.lang.VMThread.sleep(Native Method)
      at java.lang.Thread.sleep(Thread.java:1044)
      at java.lang.Thread.sleep(Thread.java:1026)
      at com.example.androidyue.bitmapdemo.MainActivity$1.run(MainActivity.java:27)
      at android.app.Activity.runOnUiThread(Activity.java:4794)
      at com.example.androidyue.bitmapdemo.MainActivity.onResume(MainActivity.java:33)
      at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1282)
      at android.app.Activity.performResume(Activity.java:5405)

    假如是线上版本引起的,Google Play后台有相关的数据可以帮助查看分析并解决问题。

    细致分析

    提问: BroadcastReceiver过了60秒居然没有ANR? 现场代码如下

     public class NetworkReceiver extends BroadcastReceiver{
        private static final String LOGTAG = "NetworkReceiver";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(LOGTAG, "onReceive intent=" + intent);
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.i(LOGTAG, "onReceive end");
        }
    }

    回答:实际上已经发生了ANR,只是没有进行对话框弹出而已。这种ANR就是background ANR,即后台程序的ANR,我们可以通过过滤日志验证

     adb logcat | grep "NetworkReceiver|ActivityManager|WindowManager"
    I/NetworkReceiver( 4109): onReceive intent=Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x8000010 cmp=com.example.androidyue.bitmapdemo/.NetworkReceiver (has extras) }
    I/ActivityManager(  462): No longer want com.android.exchange (pid 1054): empty #17
    I/NetworkReceiver( 4109): onReceive end
    W/BroadcastQueue(  462): Receiver during timeout: ResolveInfo{5342dde4 com.example.androidyue.bitmapdemo.NetworkReceiver p=0 o=0 m=0x108000}
    E/ActivityManager(  462): ANR in com.example.androidyue.bitmapdemo
    E/ActivityManager(  462): Reason: Broadcast of Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x8000010 cmp=com.example.androidyue.bitmapdemo/.NetworkReceiver (has extras) }
    E/ActivityManager(  462): Load: 0.37 / 0.2 / 0.14
    E/ActivityManager(  462): CPU usage from 26047ms to 0ms ago:
    E/ActivityManager(  462):   0.4% 58/adbd: 0% user + 0.4% kernel / faults: 1501 minor
    E/ActivityManager(  462):   0.3% 462/system_server: 0.1% user + 0.1% kernel
    E/ActivityManager(  462):   0% 4109/com.example.androidyue.bitmapdemo: 0% user + 0% kernel / faults: 6 minor
    E/ActivityManager(  462): 1.5% TOTAL: 0.5% user + 0.9% kernel + 0% softirq
    E/ActivityManager(  462): CPU usage from 87ms to 589ms later:
    E/ActivityManager(  462):   1.8% 58/adbd: 0% user + 1.8% kernel / faults: 30 minor
    E/ActivityManager(  462):     1.8% 58/adbd: 0% user + 1.8% kernel
    E/ActivityManager(  462): 4% TOTAL: 0% user + 4% kernel
    W/ActivityManager(  462): Killing ProcessRecord{5326d418 4109:com.example.androidyue.bitmapdemo/u0a10063}: background ANR
    I/ActivityManager(  462): Process com.example.androidyue.bitmapdemo (pid 4109) has died.

    除了日志,我们还可以根据前面提到的查看traces.txt文件。

    提问:可以更容易了解background ANR么?

    回答:当然可以,在Android开发者选项—>高级—>显示所有”应用程序无响应“勾选即可对后台ANR也进行弹窗显示,方便查看了解程序运行情况。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    严重缩水!NVIDIA将推中国特供RTX 5090 DD:只剩24GB显存

    00:17

    技术热点

    在windows 7桌面右键菜单上添加直接卸载USB设备的快捷菜单选项

    12个Java长久占居主要地位的原因

    SQL Server创建数据库的命令

    SQL Server 带列名导出到excel的实际操作

    MySQL字符串连接函数repeat()

    使用SQL Server日志转移实现高可用性

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。