Android中为什么主线程不会因为Looper.loop()方法造成阻塞

在android中如果主线程中进行耗时操作会引发ANR(Application Not Responding)异常。

造成ANR的原因一般有两种:

1.当前的事件没有机会得到处理

2.当前的事件正在处理,但没有及时完成

主线程中的Looper.loop()一直无限循环检测消息队列中是否有新消息为什么不会造成ANR?

ActivityThread.java 是主线程入口的类,它实际上并非线程,只是运行在主线程,它的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了

因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。

 ActivityThread 对应的 Handler 就是内部类 H,其继承 Handler,根据handleMessage 的小部分代码可以看出Activity 的生命周期都有对应的 case 条件:



主线程的死循环一直运行是不是特别消耗CPU资源呢?

其实不然,这里就涉及到Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源

你可能感兴趣的:(Android中为什么主线程不会因为Looper.loop()方法造成阻塞)