你真的了解ANR吗?

对于ANR,只要是一个在逐渐成为流弊的工程师的成长路上,或多或少都应该碰到过,什么?你没碰到过?对不起,你真流弊,惹不起惹不起。
惹不起.png

ANR定义

程序触发ANR:

当您的活动位于前台时,您的应用在5秒内无法响应输入事件或(例如按键或屏幕触摸事件),会弹出ANR弹窗。

位于后台时候:任务在在主线程中相当长的时间内未完成执行,也会触发ANR,但是无弹窗提示,显示卡死状态(后台ANR对话框并不总是显示给用户,可以在开发者选项里打开)

总结:Android应用程序的UI线程被阻止太长时,会触发“应用程序无响应”(ANR)错误。

出现ANR的条件
1 该应用程序在主线程上执行耗时操作(大量的数据处理,复杂的计算等之类的)。
2 主线程正在对另一个进程(workThread)执行同步绑定器调用,而workThread进程需要执行很长时间才能返回。
3 主线程被阻塞,等待在另一个线程上发生的长操作的结果才能继续进行。
4 主线程与另一个线程处于死锁状态,无论是在您的进程中还是通过绑定器调用。

解决问题

普通情况
对于耗时操作:统一丢到子线程去处理

其他情况

锁争用
在某些情况下,导致ANR的工作不会直接在应用程序的主线程上执行。如果工作线程持有主线程完成其工作所需的资源的锁定,则可能发生ANR。


例子.png
@Override
public void onClick(View v) {
    // The worker thread holds a lock on lockedResource
   new LockTask().execute(data);

   synchronized (lockedResource) {
       // The main thread requires lockedResource here
       // but it has to wait until LockTask finishes using it.
   }
}

public class LockTask extends AsyncTask<Integer[], Integer, Long> {
   @Override
   protected Long doInBackground(Integer[]... params) {
       synchronized (lockedResource) {
           // This is a long-running operation, which makes
           // the lock last for a long time
           BubbleSort.sort(params[0]);
       }
   }
}

上面代码可以看出,lockedResource加锁了,如果在LockTask异步任务未执行完成,锁不会释放,主线程这个时候也需要用到lockedResource,就卡在这里了,要避免这种逻辑的出现。

死锁
当线程进入等待状态时发生死锁,因为另一个线程持有所需的资源,该线程也在等待第一个线程持有的资源。如果应用程序的主线程处于这种情况,则可能会发生ANR。

广播接收器

ANR在以下情况下发生:
1.广播接收器onReceive()方法在相当长的时间内未完成其方法的执行。
2.广播接收器使用goAsync()生成PendingResult对象,让PendingResult继续去执行任务,事后PendingResult未调用finish()方法导致ANR。

public void onReceive(Context context, final Intent intent) {
  final PendingResult pendingResult = goAsync();
  new AsyncTask<Integer[], Integer, Long>() {
   @Override
   protected Long doInBackground(Integer[]... params) {
       // This is a long-running operation
       BubbleSort.sort(params[0]);
       pendingResult.finish();
   }
 }.execute(data);
}

注意:广播接收器可用于goAsync()向系统发出信号,表明它需要更多时间来处理消息,需要在子线程去处理,完事后记得pendingResult.finish()。

关于广播接收器goAsync()的使用,感兴趣的可以自行了解。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,881评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,116评论 25 708
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,869评论 2 59
  • 一个人到底要经历了多少事情才会说出:“人的一生,会遇到形形色色的人,像我这样的人,早就习惯了。”这样的话。 不知道...
    西边日出阅读 316评论 0 2
  • 妈妈说,我家有三个宝贝:俩大宝贝,还有一个小宝贝。 可乐是只泰迪狗,当你听了以下的故事,便会觉得这是一段奇...
    婷婷玉立_3a00阅读 270评论 0 1