Android性能之 ANR 分析解决

ANR全名Application Not Responding, 也就是"应用无响应". 当操作在一段时间内系统无法处理时, 系统层面会弹出上图那样的ANR对话框.

产生ANR原因

在Android里, App的响应能力是由Activity Manager和Window Manager系统服务来监控的. 通常在如下两种情况下会弹出ANR对话框:

  1. 5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
  2. BroadcastReceiver在10s内无法结束.

造成以上两种情况的首要原因就是在主线程(UI线程)里面做了太多的阻塞耗时操作, 例如文件读写, 数据库读写, 网络查询等等.

如何避免ANR

知道了ANR产生的原因, 那么想要避免ANR, 也就很简单了, 就一条规则:

不要在主线程(UI线程)里面做繁重的操作.

可能产生ANR的条件

  1. 普通阻塞导致的ANR
  2. CPU满负荷,这时候一般会在 trace中最后一句看到(100%TOTAL: 5.9% user + 4.1% kernel + 89% iowait)
  3. 内存原因(其实内存原因有可能会导致ANR, 例如如果由于内存泄露, App可使用内存所剩无几, 我们点击按钮启动一个大图片作为背景的activity, 就可能会产生ANR)

ANR的处理

针对三种不同的情况, 一般的处理情况如下

  1. 主线程阻塞的

开辟单独的子线程来处理耗时阻塞事务.

  1. CPU满负荷, I/O阻塞的

I/O阻塞一般来说就是文件读写或数据库操作执行在主线程了, 也可以通过开辟子线程的方式异步执行.

  1. 内存不够用的

增大VM内存, 使用largeHeap属性, 排查内存泄露(这个在内存优化那篇细说吧)等.

知识点

哪些地方是执行在主线程的
  1. Activity的所有生命周期回调都是执行在主线程的.
  2. Service默认是执行在主线程的.
  3. BroadcastReceiver的onReceive回调是执行在主线程的.
  4. 没有使用子线程的looper的Handler的handleMessage, post(Runnable)是执行在主线程的.
  5. AsyncTask的回调中除了doInBackground, 其他都是执行在主线程的.
  6. View的post(Runnable)是执行在主线程的.
使用子线程的方式有哪些
  1. 启Thread方式(继承Thread、实现Runnable接口)
  2. 使用AsyncTask
  3. HandlerThread
  4. IntentService
  5. Loader

你可能感兴趣的:(Android性能之 ANR 分析解决)