最近看到一个问题:Android中为什么主线程不会因为Looper.loop()里的死循环卡死,在知乎上看到这个问题的讨论后,记录一下自己简单的总结看法。
-
从系统角度讲,主线程就是一个线程。对于线程既然是一段可执行的代码,当可执行代码执行完成后,线程生命周期便该终止了,线程退出。而对于主线程,我们是绝不希望会被运行一段时间,自己就退出,那么如何保证能一直存活呢?简单做法就是可执行代码是能一直执行下去的,死循环便能保证不会被退出。所以,从这一点来讲就是需要有一个死循环来保证主线程一直存活。
-
从Android消息机制上来讲,Android消息处理包括三部分:消息循环,消息分发和处理。Looper.loop() 这个方法在主线程循环着,当有消息的时候就进行消息处理,然后在这个循环里面去执行的,当然不会阻塞了;没有消息线程就挂起,让出CPU资源,等待唤醒。
-
从题目理解上来说,要区分阻塞和卡死,具体可以说是”Looper.loop()的阻塞“和”UI线程上执行耗时操作卡死“的区别。首先这两点之间一点联系都没有,完全两码事。Looper上的阻塞,前提是没有输入事件,MsgQ为空,Looper空闲状态,线程进入阻塞,释放CPU执行权,等待唤醒。UI耗时导致卡死,前提是要有输入事件,MsgQ不为空,Looper正常轮询,线程并没有阻塞,但是该事件执行时间过长,而且与此期间其他的事件(按键按下,屏幕点击..)都没办法处理(卡死),然后就ANR异常了。
网友评论