android中的ANR总结

1. 背景介绍

    ANR:application not responding,就是应用程序未响应,这个是google为了提高用户体验,使得应用程序在一定的时间内响应用户操作,不然用户有权关闭这个应用。

    我们常见到的ANR分为以下几类:

    1. event ANR:就是应用程序需要在5s的时间内去处理一个由底层上报上来的event,可以是key,也可以是touch时间。当然如果只有一个事件的话是不会发生ANR的,只有后面还有事件需要处理才会对当前正在执行的事件计时,如果超过5s就会弹出anr的对话框。

   2. Service的ANR,service的ANR是service的onCreate方法的执行时间不能超过20s。Service的超时判断是按照process来进行的,当启动一个service之后,判断process的service列表是否为空,如果为空,就创建一个service列表,会在20s之后发送一个message。如果列表不为空,就将service加入列表中。将当前的时间赋给刚启动的service的开始执行时间。对于一个process而言,只要有一个service之后,都是会查询它的service列表,判断是否有超时的,如果有超时的就去处理。如果无超时的,就将最先发生的service的启动时间加上20s作为下一次去判断是否有超时的service。如果没有超时的service,那么就会移除这个message,同时设置下次去查询的时间点。也就是这里用于查询的message在没有超时的情况下会被remove掉。

   3. BroadcastReceiver 的ANR,我们知道,send一个broadcast的时候会有三种情况,有普通的,有ordered的,还有就是sticky的broadcas,在这里只有ordered的broadcast才会发生超时。另外要说明的一点就是所有在AndroidManifest中注册的receiver都会被当做是ordered的broadcast来处理。这句话的意思就是说当我们send一个normal的broadcast的时候,如果有在AndroidManifest中注册的receiver的话,就会分为2种方式,一种就是并发执行,而对于那些在注册文件里的会串行的去执行。我想的话,google这么做的目的可能是觉得在manifest文件里注册的receiver,这个进程可能没起来,如果没起来的话,那就会先启动进程,在启动receiver,而进程的启动也是会有ANR的,也就是10s。

    当需要广播intent,会发送一个消息BROADCAST_INTENT_MSG,接下来会调用processnextbroadcast(),会进行一个判断,如果是串行发送的就会设置一个超时时间,在那个时间发送消息,检查是否超时。如果超时就会调用broadcastTimeoutLocked()来进行处理,将它的执行结果设为空,终止当前receiver的执行。然后转而处理下一个。当广播到最后一个的时候,会取消超时的设定。对于这种消息处理的方式和service中是会有明显不同的,那就是不管超时与否,都会处理这个消息,如果超时就会终止当前执行,如果没有超时就会将下一个的超时检查时间点设置好,在重新发送一个消息。这2种方式估计是google不同的人写的,至于效率如果,笔者也不敢妄下定论。

    这里给我们提了个醒,不要再receiver的onReceive方法中做很多繁重的任务,如果确实需要做的话,可以用goAsync方法,然后在新开一个线程去执行。还有如果是在文件里注册的receiver,它的onReceive里也是不能去执行一些异步的函数。

  总结一下,ANR最常见的就是这么几种,当我们遇到ANR的时候可以分析log,anr的log在手机上的/data/anr/traces.txt,当遇到anr的时候可以参照这个文件看一下究竟是什么地方发生了ANR。希望对大家有用。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值