Android---ANR问题分析

news2024/9/21 19:00:54

目录

ANR 概念

超时检测机制

如何避免 ANR 问题?

ANR 分析

ANR 问题线上监控


ANR 概念

ANR(Application Not Response),是指应用程序未响应,Android 系统对于一些事情需要在一定时间范围内完成,如果超过预定时间未能得到有效响应或者响应时间过长,都会造成 ANR。

在 Android 里,应用程序的响应是由 Activty Manager 和 WindowManager 系统服务监视的。当它监测到以下情况中的一个时,Android 就会针对特定的应用程序显示 ANR:

\bullet Service Timeout

\bullet BroadcastQueue Timeout

\bullet ContentProvider Timeout

\bullet InputDispatching Timeout

Timeout 时长

\bullet 对于前台服务,超时则为:SERVICE_TIMEOUT = 20s;

\bullet 对于后台服务,超时则为:SERVICE_BACKGROUND_TIMEOUT = 200s;

\bullet 对于前台广播,超时则为:BROADCAST_FG_TIMEOUT = 10s;

\bullet 对于后台广播,则超时为:BROADCAST_BG_TIMEOUT = 60s;

\bullet ContentProvider 超时为 CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s;

\bullet InputDispatching Timeout: 输入事件分发超时 5s ,包括按键和触摸事件

注意:Input 的超时机制与其它的不同,对于 Input 来说即便某次事件执行时间超过 timeout 时长,只要用户后续没有再生成输入事件,则不会触发 ANR。

超时检测机制

1. Service 超时检测机制:

        超过一定时间没有执行完相应操作来触发移除延时信息,则会触发 ANR;

2. BroadcastReceiver 超时检测机制:

        有序广播的总执行时间超过 2*receiver 个数 * timeout 时长,则会触发 ANR;

        有序广播的某一个 receiver 执行过程超过 timeout 时长,则会触发ANR;

3. 另外:

        对于 Service,Broadcast,input 发生 ANR 之后,最终都会调用 AMS.appNotResponding; 

        对于 provider, 在其进程启动时 publish 过程可能会出现 ANR,则会直接杀进程以及清理相应

        信息,而不会弹出 ANR 对话框;

如何避免 ANR 问题?

考虑上面的 ANR 定义,让我们来研究一下为什么它会在 Android 应用程序里发生和如何构建最佳应用程序来避免 ANR。

1. Android 应用程序通常是运行在一个单独的线程(例如,main)里。这意味着你的应用程序所做事情如果在主线程里占用了台词的时间的话,就会引发 ANR 对话框,因为你的应用程序并没有给自己机会来处理输入事件或者 Intent 广播。

2. 运行在主线程里的任何方法都尽可能少做事情。特别是,Activity 应该在它的关键生命周期方法(如 onCreate() 和 onResume())里尽可能少的去做创建操作。潜在的耗时操作,如网络数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里来完成。然而,不是说你的主线程阻塞在哪里等待子线程的完成,也不是调用 Thread.wait() 或者 Thread.sleep()。代替的方法是,主线程应该为子线程提供一个 Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性并能避免由于 5s 输入事件的超时引发的 ANR 对话框。这种做法应该在其它显示 UI 的线程里效仿,因为它们都受到相同的超时影响。

3. IntentReceiver 执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的工作如保存设定或者注册一个 Notification。和在主线程里调用的其它方法一样,应用程序应该避免在 BroadcastReceiver 里做耗时的操作或计算。但不再是在子线程里做这些任务(因为 BroadcastReceiver 的生命周期短),代替的是,如果响应 Intent 广播需要执行一个耗时的动作的话,应用程序应该启动一个 Service。同时,也应该避免在 IntentReceiver 里启动一个 Activity ,因为它会创建一个新的画面,并从当前用户正在运行的程序抢夺焦点。如果你的应用程序在响应 Intent 广播是需要向用户展示什么,你应该使用 Notification Manager 来实现。

4. 增强响应灵命性

一般来说,在应用程序里,100--200ms 是用户能感知阻滞的时间阈值。因此,这里有一些额外的技巧来避免 ANR,并有助于让你的应用程序看起来有响应性。

如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBar 和 ProgressDialog 对这种情况来说很有用)。

5. 如果你的应用程序有一个耗时的初始化过程的话,可以考虑显示一个 SplashScreen(闪屏页)或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。

总之,主线程尽量只做 UI 相关的操作,避免耗时操作,比如过度复杂的 UI 绘制网络操作文件I/O 操作;避免主线程跟工作线程发送锁的竞争,减少系统耗时 binder 的调用,谨慎使用 sharePreference,注意主线程执行 provider query 操作。尽可能减少主线程的负载,让其空闲待命,以便随时响应用户的操作。

ANR 分析

1. 前台 ANR 发生后,系统会马上去抓取现场的信息,用于调试分析,收集的信息如下:

  \bullet 将 am_anr 信息输出到 EventLog,也就是说 ANR 触发的时间点最接近的就是 EventLog 中输出 am_anr 信息。

  \bullet 收集以下重要进程的各个线程调用栈 trace 信息,保存在 data/anr/traces.txt 文件

        a. 当前发生 ANR 的进程,system_server 进程以及所有 persistent 进程

        b. audioserver, cameraserver, mediaserver, surfaceflinger 等重要的 native 进程

        c. CPU 使用率排名前 5 的进程

  \bullet 将发生 ANR 的 reason 以及 CPU 使用情况信息输出到 main log

  \bullet 将 traces 文件和 CPU 使用情况信息保存到 dropbox,即 data/system/dropbox 目录

  \bullet 对用户可感知的进程则弹出 ANR 对话框告知用户,对用户不可感知的进程发生 ANR 则直接杀掉

2. 分析步骤

  \bullet 定位发生 ANR 的时间点

  \bullet 查看 trace 信息

  \bullet 分析是否有耗时的 message, binder 调用,锁的竞争,CPU 资源的抢占

  \bullet 结合具体的业务场景的上下文来分析

解决 ANR 问题

ANR 问题线上监控

1.  FileObserver: 可以监控某个目录/文件状态是否发生改变,或者有没有在某个目录下创建/删除文件,再或者往某个文件里添加内容。自定义 class extends FileObserver , 然后去监听 /data/anr/ 目录,如果该目录发生了变化,说明肯定是有 ANR 问题产生了。

Android 系统再此基础上封装了一个 FileObserver 类来方便使用 Inotify 机制。FileObserver 是一个抽象类,需要定义子类实现该类的 onEvent 抽象方法,当被监控的文件或者目录发生变更事件时,将回调 FileObserver 的 onEvent() 函数来处理文件或目录的变更事件。

 2. WatchDog : extends Thread, 监控系统有没有死锁的情况

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VSCode作业1:猜数字游戏和简单计数器(包含完整代码)

目录 猜数字游戏 一、使用‘random’函数获取随机数 二、 分情况讨论输入值大小情况 三、HTML代码 四、CSS样式及运行效果 简单计数器(计时器) 一、使用‘setInterval’函数实现计数效果 二、使用’clearInterval‘函数实现暂停计数和重新计数效果 …

【机器学习】sklearn的集成学习用于图像分类从0到1,注意点和坑点

文章目录 前言1.需求分析1.1 场景1.2 解决方案 2. 代码2.1 提取特征2.2 构建分类器2.4 集成模型2.5 总的训练代码 3.fast api 封装4.总结 前言 深度学习崛起后,好像机器学习就没落了,但在固定场景下,还是很好用的。下面就是展厅项目的识别任…

解决Edge Dev更新后NewBing侧边栏消失的问题,并使用NewBing作画

文章目录 解决Edge Dev更新后NewBing侧边栏消失的问题,并使用NewBing作画问题来源操作步骤打开侧边栏步骤尝试让NewBing给出图像输出表情包或者其他图片使用NewBing作画 查看聊天记录插件 总结 解决Edge Dev更新后NewBing侧边栏消失的问题,并使用NewBing…

标签制作软件如何批量制作DotCode码

DotCode码是由不连续的点组成的二维条形码符号。设计的初衷是工业流水线上使用高速喷墨/激光打印机印刷产品有效期、批号以及序列号等。其尺寸是灵活可变的,可以根据货品表面的大小来调整印刷。下面带大家一起看一下在标签制作软件中如何批量制作: 打开…

STM32F4_十进制和BCD码的转换

目录 前言 1. BCD码 2. BCD码和十进制转换的算法 前言 最近在学习STM32单片机(不仅仅是32)的RTC实时时钟系统的过程中,需要配置时钟的时间、日期;这些都需要实现BCD码和十进制之间进行转换。这里和大家一起学习BCD码和十进制之…

C++函数必备简单知识

目录 1、函数的定义与声明 (1)定义 (2)声明 2、指针传参 3、引用 4、函数的引用传参 5、函数重载 overlord (1)参数数量不同 (2)参数类型不同 6、避免overlord歧义 7、内…

Opencv+Python图像像素处理

目录 二值图像的像素访问、修改 单个像素访问、修改 多个像素修改 彩色图像(三维数组) 像素访问、修改 BGR模式 像素访问、修改 二值图像的像素访问、修改 单个像素访问、修改 import numpy as np import cv2 as cv # 使用Numpy库中的函数zeros()可…

springboot登录验证

案例-登录认证 已经实现了部门管理、员工管理的基本功能,但是大家会发现,但没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,今天的主题就是登录认证。 最终要实现的效果就是用户必须登录之后,才…

Spark学习笔记【shuffle】

本文基本上是大数据处理框架Apache Spark设计与实现的Shuffle部分的学习。以及Spark基础知识Bambrow Shuffle解决啥问题 上游和下游,不同stage,不同的task之间是如何传递数据的。ShuffleManager管理ShuffleWrite和ShuffleRead 分为两个阶段&#xff1…

基于JavaWeb实现的寻码网文章资讯管理系统

一、技术结构 前端:html ajax 后端:SpringBootMybatis-plus 环境:JDK1.8 | Mysql | Maven | Redis 二、功能简介 数据库与代码截图 后端管理-登录页 后端管理-首页 后端管理-文章管理-发布文章 后端管理-文章管理-文章列表 后端管理-文…

Vue快速入门,常用指令,生命周期

Vue常用指令 案例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…

MySQL一次大量内存消耗的跟踪

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。文章来源&#xff1a;GreatSQL社区原创 线上使用MySQL8.0.25的数据库&#xff0c;通过监控发现数据库在查询一个视图(80张表的u…

【网络进阶】WebSocket协议

文章目录 1. Web实时技术的应用2. WebSocket协议介绍2.1 WebSocket的工作原理2.2 优点2.3. 使用场景2.4 实现细节 3. WebSocket服务器实现3.1 客户端代码&#xff08;HTML & JavaScript&#xff09;3.2 服务器端代码&#xff08;C&#xff09;3.3 测试结果 1. Web实时技术的…

Qt 智能指针介绍: QSharedPointer、QWeakPointer 、QScopedPointer 、QPointer(附实例)

文章目录 1. 概述2. Qt 中有几种智能指针&#xff1f;2.1 QSharedPointer 实例2.2 QSharedPointer 与 QWeakPointer 实例2.3 QScopedPointer 实例2.4 QPointer 实例 1. 概述 在使用动态内存分配的情况下&#xff0c;需要确保对象的所有权正确地被管理和转移。使用智能指针可以…

【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(一)

【前提简介】 本文档主要总结HarmonyOS开发过程中可能遇到的一些问题解答&#xff0c;主要围绕HarmonyOS展开&#xff0c;包括但不限于不同API版本HarmonyOS开发、UI组件、DevEco Studio、Gitee示例代码等&#xff0c;并将持续更新哦。 【官方FAQ】 【FAQ】HarmonyOS应用及服…

(十二)地理数据库创建——基本组成项及数据加载

地理数据库创建——基本组成项及数据加载 目录 地理数据库创建——基本组成项及数据加载 1.建立数据库中的基本组成项1.1建立要素数据集1.2建立要素类1.2.1建立简单要素类1.2.2建立关系表 1.3建立关系表 2.向地理数据库加载数据2.1导入数据2.1.1导入Shapefile2.1.2导入dBASE 表…

数据结构:顺序表的增、删,查、改实现

1.概念 顺序表是用一段 物理地址连续 的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存 储。在数组上完成数据的增删查改。 2.分类 顺序表一般可以分为&#xff1a; 2.1 静态顺序表&#xff1a;使用定长数组存储元素 这样会造成空间给多了浪费&#x…

ThreadLocal初探

一、ThreadLocal介绍 一、官方介绍 从Java官方文档中的描述&#xff1a;ThreadLocal类用来提供线程内部的局部变量&#xff0c;这种变量在多线程环境下访问&#xff08;通过get和set方法访问&#xff09;时&#xff0c;能够保证各个线程的变量相对独立于其他线程内的变量。Thr…

apple pencil必须要买吗?性价比平替电容笔排行榜

要知道&#xff0c;真正的苹果原装Pencil&#xff0c;价格实在是太贵了&#xff0c;普通的消费者根本买不起。所以&#xff0c;有没有可能出现一种平替的、功能一模一样的、与苹果Pencil一样的电容笔呢&#xff1f;这倒也是。国产的平替笔和苹果Pencil的笔相比&#xff0c;并没…

Wireless-Sensor-Network-master_WSN_无线传感网络(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 近年来&#xff0c;随着对等网络、云计算和网格计算等分布式环境的发展&#xff0c;无线传感器网络&#xff08;WSN&#xff0…