首先先明白一个问题:什么是anr?
anr意思就是应用没有响应。以前存在很多误解就是"在主线程做了耗时操作"就会引起ANR,现在觉得不完全正确,耗时操作实际上不一定会导致没有响应,没有响应的通俗理解就是:
有人(事件或操作)发出一个请求,但是主线程没有对这个人进行回馈(可能是没时间,可能是不想理,可能是没办法理你)这个就叫做没有响应。
这段代码在onCreate中sleep了10秒,会出现anr吗?
答案是可能会,也可能不会
当主线程在sleep的时候,如果UI线程不需要进行操作,也就是说没有消息会发送给UI线程并要求UI线程进行处理的时候,那么sleep30秒就不会导致ANR,因为没有出现anr的情况,既然没有人向主线程请求什么东西,也就不需要响应,既然没有响应了,那么何来说应用无响应,所以就没有anr存在了。
但是当线程在sleep的时候,主线程有接收到需要处理的请求的时候,这个时候UI线程正在Sleep,根本没有办法理你(不想理你),这就符号anr的条件,所以就会出现anr(比如在休眠10秒内,点击了返回按钮。就会出现anr)。
如下图是安卓11手机上:
虽然主线程休眠了10秒,但是在这10秒内没有事件需要处理,mButton.setText("first update")更新的操作没有在主线程sleep的时候被触发,也就没有发生ANR,
这个同上,我本以为不会发生ANR,但现象还是发生了ANR,猜测安卓11是不是主线程睡眠至少10秒一段时间。中间会有其他什么事件触发,导致发生ANR,先留个疑问在这。
延伸:Thread.sleep问题
由于cpu分配的每个线程的时间片极为短暂(一般为几十毫秒)所以,cpu通过不停地切换线程执行,这就给程序员造成一种错觉,以为是多个线程在同时进行,sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,此线程重新回到就绪状态,调用Sleep(1000)函数并不是说等该线程休眠1秒之后继续执行它,Thread.Sleep(1000) 意思是在未来的1秒内本线程不参与CPU竞争。