美文网首页
你真的了解ANR吗?

你真的了解ANR吗?

作者: 放码过来吧 | 来源:发表于2018-10-01 07:35 被阅读29次
对于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()的使用,感兴趣的可以自行了解。

相关文章

  • 你真的了解ANR吗?

    ANR定义 程序触发ANR: 当您的活动位于前台时,您的应用在5秒内无法响应输入事件或(例如按键或屏幕触摸事件),...

  • 你真的了解iOS代理设计模式吗?

    你真的了解iOS代理设计模式吗? 你真的了解iOS代理设计模式吗?

  • 你真的了解吗

    我一直都以聪明且睿智的形象出现在身边的每个人面前,但是只有自己知道我有多傻,一切都以太过匆匆忙忙。 从我...

  • 你真的了解吗?

    请别轻易的拒绝保险,买保险时,你有100句拒绝我,我却只有这6句话告诉你: 第一句:你买保险是一种睿智的选择。 买...

  • 多线程6:你以为你真的了解final吗?

    你以为你真的了解final吗?

  • 请了解自己

    你了解自己吗?了解?真的了解? 我不了解我自己

  • 素琴先生‖孩子每一个行为的背后,几乎都是关系的问题。

    “我自己的孩子,我还能不了解吗?” 但事实上,真的如你所说吗?你真的了解你孩子吗? 其 实我们所说的了解仅仅是了解...

  • 你真的了解你吗

    吃到蛋糕还想再来一口, 有茶喝然后一直追寻好茶, 杯中有酒然后味觉却在寻找, 生活无忧然后开始想高收入, …… 太...

  • 了解 Android ANR

    前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接,demo链接 合理编写...

  • 了解 Android ANR

    合理编写在世界各地获得性能测试的代码,但仍然觉得缓慢,挂起或冻结很长时间,或者花费太长的时间来处理输入。应用程序响...

网友评论

      本文标题:你真的了解ANR吗?

      本文链接:https://www.haomeiwen.com/subject/nwpwoftx.html