Android ANR发生的原因总结和解决办法

2018-11-17 21:05:48

ANR的全称是application not responding,是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择继续等待或者Force Close。


首先ANR的发生是有条件限制的,分为以下三点:


只有主线程才会产生ANR,主线程就是UI线程;

必须发生某些输入事件或特定操作,比如按键或触屏等输入事件,在BroadcastReceiver或Service的各个生命周期调用函数;

上述事件响应超时,不同的context规定的上限时间不同

a.主线程对输入事件5秒内没有处理完毕


b.主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕


c.主线程在前台Service的各个生命周期函数时20秒内没有处理完毕(后台Service200s)。


那么导致ANR的根本原因是什么呢?简单的总结有以下两点:

1.主线程执行了耗时操作,比如数据库操作或网络编程,I/O操作


2.其他进程(就是其他程序)占用CPU导致本进程得不到CPU时间片,比如其他进程的频繁读写操作可能会导致这个问题。


细分的话,导致ANR的原因有如下几点:


耗时的网络访问


大量的数据读写


数据库操作


硬件操作(比如camera)


调用thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候


service binder的数量达到上限


system server中发生WatchDog ANR


service忙导致超时无响应


其他线程持有锁,导致主线程等待超时


其它线程终止或崩溃导致主线程一直等待


那么如何避免ANR的发生呢或者说ANR的解决办法是什么呢?

1.避免在主线程执行耗时操作,所有耗时操作应新开一个子线程完成,然后再在主线程更新UI。


2.BroadcastReceiver要执行耗时操作时应启动一个service,将耗时操作交给service来完成。


3.避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。


  • 2020-02-19 23:04:52

    理解Laravel中的pipeline

    pipeline在laravel的启动过程中出现次数很多,要了解laravel的启动过程和生命周期,理解pipeline就是其中的一个关键点。网上对pipeline的讲解很少,所以我自己写一写吧。

  • 2020-02-19 23:08:56

    Laravel 用户认证 Auth(精华)

    很多应用是需要登陆后才能操作,Laravel 提供了一个 auth 工具来实现用户的认证功能。并且有一个 config/auth.php 来配置 auth 工具。大概看一下 auth 工具的常用方法

  • 2020-02-19 23:12:44

    Laravel 从 $request 到 $response 的过程解析二(必读)

    laravel 的请求会组装成 $request 对象,然后会依次经过中间件(前置部分),最终到达 url 指向的控制器方法,然后把返回数据组装为 $response 对象返回,再依次经过中间件 (后置部分),最终返回。

  • 2020-02-19 23:15:24

    PHP 闭包(Closure)

    闭包(Closure)又叫做匿名函数,也就是没有定义名字的函数。比如下面的例子: