Android ANR

文章详细介绍了AndroidANR(应用程序无响应)的概念,包括其触发条件、避免策略和不同类型的ANR。ANR主要发生在主线程阻塞、资源耗尽等情况。文章还讨论了如何通过logcat、trace文件和系统监控来定位和解决ANR问题,并提出了线上监控ANR的两种方案:FileObserver和WatchDog机制。同时,文章提到了Selinux在Android安全中的作用,并列举了一些相关技术知识点。

Android ANR

本文链接:https://blog.youkuaiyun.com/feather_wch/article/details/131648541

ANR概念和原因

1、ANR

  1. 应用程序无响应(非Activity无响应)
  2. 指的是在特定时间内,无法响应输入事件或者特定事件没有处理完成
    2、ANR(Application Not Response)类型
  3. 点击事件 5s未处理完,且有下一个输入事件
  4. 广播-前台(10s),后台(60s)
  5. 服务-前台20s,后台200s
  6. ContenProvider-10s未处理完
    3、ANR避免的操作
  7. ->主线程进行IO(网络、文件、序列化)
  8. ->多线程操作的死锁,导致主线程被block
  9. 主线程被Binder对端Block,Binder(默认同步,可以异步-oneway)
  10. systemserver中watchDog出现ANR

软件看门口,SystemrServer死亡后无法喂狗,会通知到父进程zygote,zygote会杀死自己。zygote爸爸init发现zygote的死亡信号,会杀死所有zygote的子进程并且重启zygote。整个系统相当于重启一次。
SystemServer的问题一般和kernel没关系,软件看门狗就可以解决

  1. 系统资源被耗尽(管道、CPU、IO)-app开发者没办法处理,系统开发者
  2. Service Binder的链接达到上限,无法和SystemServer通信
    4、多核(8核)手机的相关知识
  3. 8核并非完全一致:0-3小核 4-5中核 6-7大核
  4. 手机厂商发现要运行王者荣耀等游戏时直接绑定到中核+大核上
  5. 高通等手机厂商提供了cpuset指令,给上层用,去绑定核心
    • 其他App缺乏系统资源去处理就容易ANR
      5、ANR IO实战场景
  6. realm数据库,号称可以在UI线程进行IO,onLayout->systrace(都是微秒级别)通过了测试机和测试部测试,硬件好,软件少,内存不老化。上线后Bugly抛出大量线上ANR
  7. 主线程sp操作

ANR定位和解决

6、线下场景定位

  1. logcat : 可以定位到代码位置
  2. 文件生成在/data/anr/trace_.txt
    7、线上场景两大问题:anr和oom
  3. bugly可以集成检测或者自己实现anr监控方案
  4. 手机品牌、型号、配置+日志信息(确定大概位置)-用目标手机去跑monkey复现
  5. xxx
    8、trace_*.txt文件包含哪些内容?
  6. firstPid:发生anr的PID
  7. 有发生时间点,CPU使用率等信息
  8. 有AMS实现该功能,通过 appNotResponding()和dumpStackTrace()来生成应用对应的anr文件
  9. 通过firstPid可以关注主线程状态 + 其他线程状态
ANR时间 2023年7月7日14:46:21
进程PID 1480
进程名 com.xxx.mobile
ANR类型 KeyDispatchTimeout

9、线程底层的状态 -1~9 11种,Java层面上层 6种状态

  1. 未定义 -1
  2. 僵尸 0
  3. 运行 1
  4. time wait 2 Object.wait
  5. xxx
  6. copy一份吧
    10、分析trace文件实战
  7. 看CPU占用率 -> 1. kernel CPU很高(主线程IO) 2. 整体CPU使用量100%, 系统资源耗尽
  8. Heap内存情况 -> 排除系统资源耗尽等问题
  9. 搜索held by字段,看死锁问题
  10. 看线程 main held mutexes
    11、traces_SystemServer_WDT.txt(watchDog)
  11. WatchDog中实现
  12. 包含system_server进程栈信息
    12、traces.txt(dalvik.vm.stack-trace-file)
  13. 系统定义的默认trace文件路径
    13、可以以命令方式直接生成trace文件

adb shell kill -3 pid

ANR线上监控

14、ANR线上监控方案一:原生方案FileObserver

  1. 抽象类,onEvent()回调
  2. 监控某个目录/文件的状态发生改变(创建,删除目录)-具有八种状态
  3. 自定义实现FileObserver: 监控 data/anr/ 目录是否发生变化,肯定产生了ANR
  4. 上传trace文件,可以捞到所有ANR信息(也可能有别人APP的)
    15、FileObserver 会不会被 selinux挡住?
  5. 5.0之后肯定会,手机厂商有办法修改 selinux .te配置文件 => 适合灰度发布(全面改版功能,先小范围发布)
    16、ANR线上监控方案二:WatchDog方案
  6. WatchDog集成自线程,是单例,
  7. 内部有HandlerCheck,把自己加到handler中,一直运行,默认30秒看是否可以执行。
  8. 可以:代表主线程没有卡住,有一些处理逻辑,会进行dump createAnrDumpFile()写入到trace文件中
  9. 可以借鉴WatchDog方案:定时post、并且检查run()是否运行过了
    17、WtachDog会有性能损耗,看需求
    18、WatchDog源码里面学习假唤醒
  10. 预防【假唤醒】,采用 wait(timeout) 进行等待
  11. 可能没到timeout就唤醒了,会计算是否睡满了timeout,没有睡满直接继续wait
  12. 假唤醒概率极低,但会发生
    19、扩展:LeakCanary
  13. leakCanary.watch()
  14. 5s后会去检测对象有没有释放

最终问题汇总

20、ANR问题如何定位

  1. 线下和线上
  2. 线下:logcat日志+trace文件确定anr发生时间点

扩展开胃菜

selinux

1、Linux 安全模型 -> seAndroid 保护系统信息

常问知识点

1、并发synchronized原理、renentrantlock、CAS、AQS(CLH)
2、Java集合框架 HashMap
3、JVM 内存模型 classloader
4、Hadnelr、ASM(startActivity 从整体结构去讲解)
5、性能优化:内存优化(Bitmap)、卡顿优化
6、网络 http版本区别、https认证过程(一定安全吗?)
7、数据结构:链表、二叉树

### 分析和解决 Android 应用中的 ANR(Application Not Responding)问题 Android 中的 ANR(Application Not Responding)是指应用程序在一定时间内没有响应用户的输入事件或未能及时完成特定组件的操作,系统会判定为应用无响应,并弹出 ANR 对话框。分析和解决 ANR 问题对于提升应用的稳定性与用户体验至关重要。 #### ANR 的类型与触发机制 ANR 主要有以下几种类型,每种类型的触发时间阈值不同: - **Input Event Timeout(输入事件超时)**:主线程在 5 秒内未响应输入事件,例如点击、滑动等。 - **Broadcast Timeout(广播超时)**:前台广播在 15 秒内未完成,后台广播在 60 秒内未完成。 - **Service Timeout(服务超时)**:前台服务在 20 秒内未完成,后台服务在 200 秒内未完成。 - **ContentProvider Timeout(内容提供者超时)**:在 10 秒内未发布内容提供者。 这些机制确保了系统资源的合理调度和用户体验的流畅性。 #### ANR 日志的获取方法 为了分析 ANR 问题,首先需要获取相关的日志信息: - **实时日志捕获**:使用 `adb logcat -v time | grep "ANR in\|am_anr"` 过滤 ANR 关键词。 - **导出 traces 文件**:通过 `adb pull /data/anr/traces.txt` 获取线程堆栈信息(每次新的 ANR 会覆盖旧文件)。 - **完整系统报告**:使用 `adb bugreport` 获取包含 CPU、内存、I/O 等系统数据的完整报告。 这些日志提供了关于 ANR 发生时的应用状态、线程状态和系统资源使用情况。 #### ANR 的核心分析流程 分析 ANR 日志的流程主要包括以下几个步骤: 1. **确认 ANR 类型**:根据日志中的关键词确定 ANR 的具体类型。 2. **分析 trace 文件**:查看线程堆栈信息,识别主线程是否被阻塞、是否存在锁竞争或 Binder 线程耗尽等问题。 3. **定位根因**:通过分析 trace 文件中的调用栈和线程状态,确定 ANR 的根本原因。 #### ANR 治理方案 治理 ANR 问题需要从多个方面入手: - **透彻理解机制**:掌握 Input、Service、Broadcast 和 Binder 等超时机制,以及系统调度原理。 - **强大的监控体系**:线上平台需要抓取 ANR 事件、主线程堆栈和系统 Traces 文件;线下使用 Systrace、Perfetto、Profiler 和 `adb bugreport` 工具进行分析。 - **精准根因分析**:区分主线程阻塞、Binder 线程耗尽、系统资源瓶颈等问题,利用 Traces 文件分析锁和线程状态是关键突破口。 - **针对性优化**: - **主线程优化**:避免在主线程上执行耗时操作,优化布局和视图层次。 - **Binder 调用优化**:异步化 Binder 调用,优化服务端性能。 - **系统资源优化**:关注 CPU、内存和 I/O 使用情况,避免资源瓶颈。 - **现代化架构**:采用 WorkManager、协程/RxJava、响应式架构和生命周期感知组件,提高应用的响应能力。 - **闭环流程与文化**:设定目标、监控告警、深度分析、有效修复、严格验证、灰度发布、持续复盘和知识沉淀。将稳定性(特别是 ANR 率)作为核心质量指标。 #### 使用工具分析 ANR 问题 - **Android Profiler**:通过 Android Studio 的 Profiler 工具可以实时监控 CPU、内存和网络使用情况,帮助识别 ANR 的潜在原因。 - **StrictMode**:在开发阶段启用 StrictMode 可以检测主线程上的违规操作,如网络请求或数据库操作,从而提前发现可能导致 ANR 的问题。 #### 示例代码:使用 StrictMode 检测主线程违规操作 ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .penaltyLog() .build()); } } ``` 通过上述代码,可以在开发阶段检测主线程上的磁盘读取操作,并记录日志以便优化。 --- #### 相关问题 1. 如何通过 Systrace 工具分析 ANR 问题? 2. Android 中如何优化主线程的性能以避免 ANR? 3. 如何在生产环境中监控和捕获 ANR 事件? 4. Android 中如何处理 Binder 线程耗尽导致的 ANR 问题? 5. 如何通过响应式架构减少 ANR 的发生?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值