2024年3月27日发(作者:)

anr原理(一)

ANR原理

什么是ANR

ANR全称为“Application Not Responding”,翻译为“应用无响应”。

当Android系统中一个应用程序在处理用户操作或者Service完成后

台任务等情况时出现了阻塞,一直处理不完或响应不及时,系统便会

弹出ANR对话框,要求用户选择“等待”或“关闭应用”。

ANR原理

ANR的出现是由于Android平台中各个组件之间是运行在进程之中的,

如果某一个组件执行函数耗时过多,那么便会导致整个进程执行时间

变长,如果超出响应时间阈值,系统就会认为进程已经无响应。

ANR检测

Android系统中,ANR检测是通过binder机制实现的。主线程和UI线

程是一个线程,是在ActivityThread类的main()方法中启动的,每次

消息循环(即Handler的Looper中不断循环run()方法)执行完成后,

都会发送一个消息给ActivityThread中操作系统的binder实现的一

个服务,请求检测当前应用程序是否已经发生ANR异常。

ANR解决方法

在Android应用程序中如果出现ANR异常,开发者需要根据系统提示

信息提供详细日志信息,并对程序进行调试,找到引起ANR异常的原

因所在,并对其进行优化处理,以减少ANR的出现。

以下是一些可能导致ANR异常的原因:

• 数据库操作需要在子线程中,如果在主线程进行大量的数据操作,

就会引起主线程阻塞,而导致ANR。

• UI绘制也要在主线程中进行,如果布局过于繁琐,或者布局中包

含过多的控件,就会导致界面卡顿,从而引起ANR。

• 非常复杂的计算和IO操作也需要在子线程中执行,如果在主线

程中执行,就会导致主线程阻塞,从而引起ANR。

总之,尽量将非UI相关的操作放入子线程中进行,避免在主线程中进

行大量计算或者IO操作,从而减少ANR的风险。

结论

ANR是Android应用程序中一个常见的问题,但是通过优化代码、降低

UI复杂度和异步操作等方法,完全可以避免ANR的出现,保证应用程

序的正常运行。

ANR常见的场景

场景一:主线程执行耗时操作

主线程负责 UI 操作和响应用户事件,如果在主线程中处理其他耗时

操作,将会导致主线程阻塞,设备无暇处理用户操作,这种情况便会

出现 ANR。

常见的主线程耗时操作包括:(但不限于)

• 加载大量数据(包括从数据库获取数据和从网络获取数据)

• 执行了一个耗时的计算任务

• Bitmap 加载和显示,图片过大,decode 压缩等操作

场景二:UI响应缓慢

虽然主要原因是在主线程中执行耗时操作,但是对于 UI 帧率来说,

受到的影响最为显著。例如:UI 动画繁琐或控件重叠等缺陷。

常见的UI性能缺陷包括:(但不限于)

• 包含大量的嵌套的布局和 UI 元素,例如 ListView、GridView

等包含大量子项的 UI。

• 控件频繁的 hide/show、visible/invisible、add/remove 等操

• 图片宽高不一致,加载到 imageView 上后,需要裁剪的操作

• 控件设置的 padding 过大

• 包含透明背景的控件背景

• 非必要的使用了自定义控件

场景三:BroadcastReceiver 引起 ANR

BroadcastReceiver 是 Android 组件之一,负责响应特定事件,但是

由于 BroadcastReceiver 通常在 UI 线程中执行,如果任务过于繁琐,

将会导致主线程出现阻塞,并引发 ANR。

常见的 Broadcast 程序导致电量耗损的情况包括:(但不限于)

• 系统广播(例如 SYSTEM_BOOT 等),处理时应注意复杂的操作。

• 经常注册接收设备启动事件的应用程序

• 经常势力网络状态变化的应用程序

场景四:Service 触发 ANR

Service 是 Android 平台上可以在后台运行的组件,由于 Service

通常在主线程中执行即可,如果任务过于繁琐,将会导致主线程出现

阻塞,并引发 ANR。

常见的 Service 导致 ANR 出现的情况包括:(但不限于)

• Service 进程本身就很耗费资源,在少量内存, CPU 加载的情

况下使用 Service 时。

• Service 所在的进程运行在VirtualMachine(虚拟机)中,导致

内存不足

• Service 执比较耗时的通信和计算等操作,可能会阻塞所在的线

程。

场景五:WindowManager

WindowManager 是 Android 相关的一个组件,负责管理 Android 的

窗口系统,提供了 Params 类,可以用于定义

窗口样式的一种方式,如果使用不当将会导致 ANR 出现。

常见的 WindowManager 导致 ANR 出现的情况包括:(但不限于)

• 全屏界面启动时,设置了太多的 WindowParams。

• 正在显示对话框时,发生超时事件。

• 在更新 View hierarchy 时频繁的初始化 LayoutParams。

• 启动时创建太多的系统窗口。

总结

ANR 是 Android 开发者平台中一个常见的问题,主要出现在主线程中

长时间处理耗时操作、UI 帧率过低、BroadcastReceiver 过于频繁、

Service 不当等情况下,应用程序需要在开发和测试过程中通过优化

代码、降低 UI 复杂度和异步操作等方法,避免 ANR 的出现,保证应

用程序的正常运行。