首页 > 其他分享 >Android ANR简介

Android ANR简介

时间:2023-07-06 13:44:24浏览次数:38  
标签:ANR 简介 应用 cpu 线程 anr Android 日志

一、ANR定义

ANR(Application Not Responding), 如果 Android 应用的界面线程处于阻塞状态的时间过长,会触发“应用无响应”(ANR) 错误。如果应用位于前台,系统会向用户显示一个对话框,如图 1 所示。ANR 对话框会为用户提供强行退出应用的选项。

当点击了Close app或者由于ANR引起了闪退之后,这时查看Logcat,一般可以发现ANR以及 /data/anr/trace.txt 等字样,可以知道出现ANR主要原因是我们在主线程做了太多耗时操作,这时你可以选择等待按钮,等待应用程序结束主线程的耗时操作,或者选择确定按钮,结束这个应用程序,ANR对于一个应用来说是不能承受之痛,其影响并不比应用发生Crash小。


二、ANR分类

出现ANR的一般有以下几种类型:

Input dispatching timed out:输入时间分发超过5s,包括按键和触屏事件。

Broadcast of Intent:前台广播需要在10s内完成,后台广播需要在60s内完成。

executing service:前台服务需要在20s内完成,后台则需要在200s内完成。

ContentProvider:几乎非常少见,publish执行未在10s内完成。

Context.startForegroundService() did not then call Service.startForeground():应用调用startForegroundService,然后5s内未调用startForeground出现ANR或者Crash,此问题属于应用未适配Android版本sdk。


三、产生ANR的原因

1. 诊断 ANR 时需要考虑以下几种常见模式:

(1) 应用在主线程上非常缓慢地执行涉及 I/O 的操作,如有复杂的layout布局、频繁的I/O操作。

(2) 应用在主线程上进行长时间的计算,如一些耗时操作。

(3) 主线程在对另一个进程进行同步 binder 调用,而后者需要很长时间才能返回。

(4) 主线程处于阻塞状态,为发生在另一个线程上的长操作等待同步的块。

(5) 主线程在进程中或通过 binder 调用与另一个线程之间发生死锁。主线程不只是在等待长操作执行完毕,而且处于死锁状态。


2. 发生ANR的进一步原因:

(1) 主线程存在耗时操作:主线程阻塞(Blocked)、挂起(suspend)、死锁、死循环、耗时操作等;

(2) cpu资源被抢占:其他进程某一时间点cpu占比高、某一刻系统的cpu占比过高,都会导致这一时间段无法抢到cpu时间片;

(3) 主线程卡在 binder 通信的对端:需要通过 binder info 查看对端信息;

(4) 系统或者应用自身可用内存紧张:系统一直在执行 lowmemory killer 操作查杀进程;

(5) 应用频繁crash:包括应用自身也容易导致前台应用出现anr的现象;

(6) 应用内存泄露;

(7) 系统原因导致:如冻结、温度过高、多媒体(音视频、编解码)、包管理、Block I/O、底层服务NE(native crash)、watchdog、内存黑洞、芯片能力等。


四、分析

1. 分析日志思路

(1) 首先在 android(logcat)日志中搜索“ANR in”关键字,通过此关键字主要查看

a. 在 logcat.txt 中查看发生ANR的应用进程、pid、类型;

b. cpu负载、内存压力、cpu使用情况等。

可以看到发生ANR的时间点、包名、原因(f89caeb是个代号不好看,在event log中可看)

07-06 06:03:52.995  1122  1262 I WindowManager: ANR in Window{f89caeb u0 com.xiaoli.gaodemap/com.xiaoli.gaodemap.AndroidMainActivity}. 
Reason:f89caeb com.xiaoli.gaodemap/com.xiaoli.gaodemap.AndroidMainActivity (server) is not responding. Waited 5000ms for MotionEvent(deviceId=-1,
eventTime=30462153000000, source=0x00001002, displayId=0, action=DOWN, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000,
buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, xCursorPosition=nan, yCursorPosition=nan,
pointers=[0: (141.0, 688.0)]), policyFlags=0x6b000000


(2) 其次查看 event (logcat -b events)日志

检索 am_anr 可以看到进入anr的App包名、时间、原因。

07-05 23:28:43.352  1122  7123 I am_anr  : [0,27646,com.xiaoli.gaodemap,949501511,Input dispatching timed out (e58f0f9 com.xiaoli.
gaodemap/com.xiaoli.gaodemap.AndroidMainActivity (server) is not responding. Waited 5000ms for FocusEvent(hasFocus=false))]


(3) 然后查看 /data/anr下的 trace日志

如:/data/anr/anr_2023-07-05-22-09-22-129

----- pid 3033 at 2023-07-05 22:09:22.145231750+0800 ----- //发生ANR的进程号和时间点
Cmd line: com.xiaoli.gaodemap  //发生ANR的进程包名
Build fingerprint: 'qti/sa8295/au8295:12/SQ3A.220705.003.A1/3763:userdebug/test-keys' //平台、版本类型
DALVIK THREADS (166): //当前进程共有166个线程
"main" prio=5 tid=1 Runnable //线程名"main",线程优先级,线程内部tid
  | group="main" sCount=0 ucsCount=0 flags=0 obj=0x70a5b778 self=0xb400007a506d4be0
  | sysTid=3033 nice=-10 cgrp=top-app sched=0/0 handle=0x7b9ce0d4f8
  | state=R schedstat=( 73482259066 4675464138 104538 ) utm=5345 stm=2002 core=7 HZ=100
  | stack=0x7ff8906000-0x7ff8908000 stackSize=8188KB
  | held mutexes= "mutator lock"(shared held)
//下面是线程的调用栈

上面列出的各字段的含义:

group: 分组,如 main、system.
sCount: 线程挂起次数。
obj: 当前线程关联的java线程对象
self: 当前线程地址
sysTid: 线程真正意义Linux下的TID。
nice: 调度优先级,默认120,此时是110.
cgrp: 线程所属的进程调度组
sched: 调度策略
handle: 函数处理地址
state: Linux线程状态
schedstat: CPU调度时间统计
utm: 用户态使用CPU时间
stm: 内核态使用CPU时间
core: 该线程最后运行的CPU核
HZ: 时钟频率,这里是10ms一次tick.
stack: 线程栈的地址空间
stackSize:栈的大小
held mutexes: 持有mutex锁的类似,有独占 exclusive 和共享 shared 两类。

Runnable 位置表示状态,有多种状态:Native(表示正在执行native方法)、Blocked、Suspended、Waiting、TimedWaiting、Runnable、Monitor、WaitingForTaskProcessor、Sleeping 等。


2. CPU使用率信息分析

从android(高通平台在android.txt,MTK平台在system*.txt)日志中,查看系统中各个进程的cpu使用率,首先关注的进程就是发生anr的进程、system_server、kswapd0、kworker和其他占比较高的进程、以及最终统计的整体cpu使用率信息。例如,如果kswapd0占比较高,就说明内存存在一定的压力;iowait很高就说明系统在一些I/O耗时操作,就可以结合上下文日志及系统日志辅助分析发生ANR的原因。如果很多进程的cpu使用率普遍较高,发生anr应用的cpu使用率较低,此时可以怀疑发生anr的应用拿不到cpu时间片导致anr等。


3. Memory角度分析

查看发生anr时间点前后的可用内存情况,以及系统查杀应用的频繁程度。


6. kernel日志分析思路

在日志中直接搜索关键字“lowmemorykiller”、“iowait”等,查看发生的时间点与发生anr的时间点是否基本对应。如果发生anr时间点附近,出现大量的lowmemorykiller日志信息,则说明当时内存已经严重紧张,可以较大概率认为是内存不足导致后台一直在查杀进程,同时影响前台应用的操作,导致前台应用操作耗时出现anr问题;如果出现iowait,则表示可能出现了I/O卡顿。


7. 综合系统功能进行整体分析

部分情况下,根据trace日志很难能够直接确定发生anr的原因,需要根据当时的系统运行情况进行辅助分析。综合当前的系统环境,可以从消息队列、系统可用内存、发热功耗、后台GC频率和时长、dex2oat耗时、冻结、频繁crash、温度过高、lowmemorykiller、root权限、system.err、system.out、binder_sample、slow operation 等角度在日志中搜索关键字进行分析。也存在这种情况,系统日志信息不足以分析出anr的问题,此时需要借助日志中的systrace日志进行详细分析,虽然说大部分时间都对不上,但是也存在对上的时候。

总之,ANR问题需要进行整体分析,结合系统中的所有关键信息共同得出发生ANR的准确结论。


五、典型实例

注,日志见:https://blog.csdn.net/feelabclihu/article/details/119962884

1. Block I/O

2. 卡GPU渲染

3. 应用适配sdk

4. 相机模块遇到的问题

5. 音频模块遇到的问题

6. 音频模块遇到的问题

7. 无焦点窗口

8. 内存泄漏

9. Binder耗尽

10. barrier阻塞

11. 消息过量

12. 内存不足

13. 应用死锁

14. MessageQueue

15. 自身NE导致

16. 权限拦截

17. 多媒体编码

18. provider问题

19. park锁耗时

20. cpu时间片不足

21. 空进程

22. 芯片性能不足

 

六、总结

1. 除了正常的接收处理超时外,也会有其他额外因素引发应用产生ANR,比如:
(1) 系统的kswapd0过高引发频繁的内存交换
(2) cpu占比过高导致无法获取足够的时间片
(3) binder资源耗尽无法及时通讯等,
这些都可以从系统日志中获取到。所以如果单凭trace日志无法分析出来的时候,我们要尽可能多的查看影响发生anr的因素,搜索关键字帮我们快速定位发生的anr问题;另外也可以通过查看日志中的systrace日志或者其他辅助信息来定位问题。

 

参考:

Android ANR问题总结_内核工匠:https://blog.csdn.net/feelabclihu/article/details/119962884
Android性能优化杂谈-如何监控和解决ANR问题?:https://blog.csdn.net/ljcITworld/article/details/104420422

 

标签:ANR,简介,应用,cpu,线程,anr,Android,日志
From: https://www.cnblogs.com/hellokitty2/p/17531930.html

相关文章

  • 如何实现Android接入 mars的具体操作步骤
    Android接入mars什么是mars?mars是腾讯开发的一套移动端网络通信方案,它是基于移动设备特点设计的高性能、低功耗的短连接通信库。mars提供了一套简单易用的API,方便开发者快速接入并实现稳定可靠的网络通信。在Android平台上,mars提供了marsxlog、marsprotobuf、marsht......
  • 解决Android监控通话状态的具体操作步骤
    实现Android监控通话状态概述在Android开发中,我们可以通过监听系统的电话状态来实现监控通话状态的功能。本文将向刚入行的小白介绍实现该功能的步骤和相应的代码。流程下面是实现Android监控通话状态的整个流程:步骤描述1.获取电话管理器实例通过获取系统的电话管......
  • “金九银十”和秋招通过率高达 95% 的 Android面试题集锦,你确定不来看看吗?
    前言已经进入七月份了,职场上的“金三银四”也早已经结束。对于求职者来说,面试是一道坎,很多人会恐惧面试,即使是工作很多年的老鸟,也可能存在面试焦虑。就今年的IT行业来说,可能真的根本没有所谓的“金三银四”或是“金九银十”。各大招聘网站或者软件上不管是大厂还是中小公司看似挂个......
  • 流式细胞文件(.fcs)结构简介
    FCS一个完整的数据集主要有以下几部分:头段(必须)从数据集的第一个字节开始,文件的第一个数据集是从文件的第一个字节开始,最小长度为58个字节。以ASCII码解析。记录内容包括文件版本号(0~5共6字节)、文本段开始字节位(10~17共8字节)、文本段结束字节位(18~25共8字节)、数据段开始字节......
  • 使用GoEasy快速实现Android原生app中的websocket消息推送
    摘要:GoEasy带来了一项令开发者振奋的消息:全面支持Android原生平台!现在,您可以在Android应用中使用最酷炫的实时通信功能,借助GoEasy轻松实现消息的发送和接收。本文将带您领略GoEasy最新版本的威力,为您的应用增添一抹鲜活的互动色彩。嗨,开发者朋友们!是时候展现您的技术才华,让您的A......
  • Android Launcher apk 授信安装
    对安装的apk进行校验,除了系统应用市场中下载的,其它渠道的apk都进行安装拦截,并且弹框提示。首先需要把验证的证书保存在数据库本地,后面需要用到然后注册系统广播,用于接收apk安装时的监听,这个广播由系统发出新装时的action‘android.intent.action.PACKAGE_ADDED替换时的......
  • android studio下载地址
    AndroidStudio3.0下载地址——高速下载https://www.androiddevtools.cn/ 谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快。下载地址:https://developer.android.google.cn/studio/archive.html选择显示全部即可看到下载地址,这里给出来了。Wi......
  • MAUI Blazor Android 输入框软键盘遮挡问题2.0
    前言关于MAUIBlazorAndroid输入框软键盘遮挡问题,之前的文章已经有了答案,MAUIBlazorAndroid输入框软键盘遮挡问题但是这个方案一直存在一点小的瑕疵在小窗模式下,界面的高度始终不正确所以本篇文章重点解决这个问题特别感谢这篇文章AndroidwebView输入框软键盘遮挡问题......
  • Android BottomNavigation底部导航栏使用
    原文地址:AndroidBottomNavigation底部导航栏使用-Stars-One的杂货小窝基本使用本文侧重点记录一些特殊的样式设置,所以基本使用这里就简单概述一下,详细图文可以去找其他人的博文1.创建对应的menu菜单文件2.xml布局引用menu菜单3.启动Activity预览效果可以使用setOnIte......
  • android Toast大全(五种情形)建立属于你自己的Toast
    Toast大全(五种情形)建立属于你自己的Toast Toast用于向用户显示一些帮助/提示。下面我做了5中效果,来说明Toast的强大,定义一个属于你自己的Toast。 1.默认效果 Java代码  1.Toast.makeText(getApplicationContext(),"默认Toast样式",Toast.LENGTH_......