真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。 主线程的死循环一直运行是不是特别消耗CPU资源呢? 其实不然,这里就涉及到Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中...
1. 首先我们不要弄混了消息等待阻塞(休眠)和消息处理阻塞,消息等待阻塞会导致主线程进入休眠,不会ANR,而消息处理阻塞会导致ANR。 2. 休眠不会阻碍主线程对新消息的感知和处理(有消息会被唤醒),但消息处理阻塞会,现在你们明白系统为什么要给主线程设置5秒的超时限制了吧。 3. 当没有消息时,queue.next()会阻塞...
因为可以说,应用的整个生命周期就是运行在这个消息循环中的,安卓是由事件驱动的,Looper.loop不断的接收处理事件,每一个点击触摸或者Activity每一个生命周期都是在Looper.loop的控制之下的,looper.loop一旦结束,应用程序的生命周期也就结束了。我们可以想想什么情况下会发生ANR,第一,事件没有得到处理,第二,事件正在处理...
(1)当前的事件没有机会得到处理(即主线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了) (2)当前的事件正在处理,但没有及时完成。 所以,ANR的形成是因为有事件处理长时间没有得到任何反应,和looper的死循环是两个问题。 Android 是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一...
主线程中Android系统已经帮我们调用了Looper.prepare方法 Looper.loop() :从MessageQueue中取出消息然后发给Handler处理 该方法中有个死循环 循环里面 MessageQueue的next方法取出消息 然后调用消息的 .target.dispatchmessage方法 target是与Message绑定的handler dispatchmessage是handler的方法里面调用了HandlerMessage方法处理消息...
本篇文章我们将深入 Native 层,一起来探究 Looper#loop() 为什么不会卡死主线程背后的原因 以下,enjoy: image.png 一、开篇 从Android 2.3 开始,Google 把 Handler 的阻塞/唤醒方案从 Object#wait() / notify(),改成了用 Linux epoll 来实现 原因是 Native 层也引入了一套消息管理机制,用于提供给 C/C++ ...
Looper 作为消息循环的核心,其内部包含了一个消息队列 MessageQueue ,用于记录所有待处理的消息;通过Looper.loop不断地从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者,可以看成是消息泵。注意,线程切换就是在这一步完成的。 MessageQueue 则作为一个消息队列,则包含了一系列链接在一起的 Message ;不要...
Looper:与线程绑定,不仅仅局限于主线程,绑定的线程用来处理消息。loop()方法是一个死循环,一直从MessageQueen里取出消息进行处理。 这几个类的作用还可以用下图解释: Looper.loop()是一个死循环,为什么不会卡死主线程呢?简单的说,就是当 MessageQueue为empty时,线程会挂起,一有消息,就会唤醒线程处理消息。关于这个...
可以看到在 ActivityThread 里 调用了 Looper.prepareMainLooper() 方法创建了 主线程的 Looper ,并且调用了 loop() 方法,所以我们就可以直接使用 Handler 了。 注意:Looper.loop()是个死循环,后面的代码正常情况不会执行。 -文完- 后续可能还会更新类似的小型知识点,相对于长篇的文章来讲我不需要花费大量的时间写...