Handler中Looper死循环为什么不会导致应用卡死?【转载整理】

博客探讨了Android中Handler的Looper死循环为何不会导致应用卡死的原因,解释了输入事件在主线程中的关键角色。文章详细介绍了Android应用启动过程,涉及ActivityThread的main()函数和消息循环机制。同时,讨论了Looper死循环如何在处理消息的同时不影响应用的正常运行,以及资源消耗情况。

产生ANR的问题不是因为主线程睡眠了,而是因为输入事件没有响应,输入事件没有响应他就没有办法唤醒这个Looper,才加了这个5秒的限制。

Handler中Looper死循环为什么不会导致应用卡死?_一朵白山茶的博客-优快云博客_looper死循环为什么不会导致应用卡死throw new RuntimeException(“Main thread loop unexpectedly exited”);}为什么每一个应用会有自己的一个main函数呢?当我们在launcher界面启动一个应用的时候,这时候,系统就会用zygote给我们分配一个虚拟机,然后,这个应用就会运行在这个虚拟机上面。应用运行到虚拟机之后,首先它要执行的就是启动ActivityThread,在ActivityThread中,它又会启动它的main()函数。在main()函数中,它最重要的两行代码https://blog.youkuaiyun.com/m0_70082867/article/details/124496702?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165949312616782350818762%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165949312616782350818762&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_v36-3-124496702-null-null.142^v39^pc_rank_v36&utm_term=Handler%20%E4%B8%AD%E7%9A%84%20Looper%20%E6%97%A0%E9%99%90%E5%BE%AA%E7%8E%AF%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B2%A1%E6%9C%89%E9%98%BB%E5%A1%9EUI%E4%B8%BB%E7%BA%BF%E7%A8%8B%EF%BC%9F&spm=1018.2226.3001.4187

“Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?”_一叶飘舟的博客-优快云博客前言Android的消息机制主要是指Handler的运行机制,对于大家来说Handler已经是轻车熟路了,可是真的掌握了Handler?本文主要通过几个问题围绕着Handler展开深入并拓展的了解。站在巨人的肩膀上会看的更远。大家有兴趣的也可以到Gityuan的博客上多了解了解,全部都是干货。而且他写的东西比较权威,毕竟也是小米系统工程师的骨干成员。QuestionsLooper 死循环为什么不会导致应用卡死,会消耗大量资源吗?主线程的消息循环机制是什么(死循环如何处理其它事https://blog.youkuaiyun.com/jdsjlzx/article/details/108222678?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-108222678-blog-112681020.pc_relevant_aa_2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-108222678-blog-112681020.pc_relevant_aa_2&utm_relevant_index=1

### Android Looper机制分析及死循环卡死的原因 Looper 是 Android 中用于管理消息队列的核心组件之一,其主要职责是不断从消息队列中取出消息并进行处理。尽管 `Looper.loop()` 方法内部实现了一个看似无尽的死循环,但系统并不会因此卡死,这得益于 Android 消息机制的设计。 #### 1. Looper 的工作原理 `Looper` 的核心功能是通过一个无限循环来不断从 `MessageQueue` 中获取消息,并将这些消息传递给对应的 `Handler` 进行处理。以下是 `Looper.loop()` 方法的主要逻辑[^5]: ```java public static void loop() { final Looper me = myLooper(); final MessageQueue queue = me.mQueue; for (;;) { // 死循环 Message msg = queue.next(); // 阻塞直到有消息到达 if (msg == null) { return; // 如果没有消息且退出条件满足,则退出循环 } try { msg.target.dispatchMessage(msg); // 将消息交给对应的 Handler 处理 } finally { msg.recycleUnchecked(); // 回收消息对象 } } } ``` - **阻塞等待**:`queue.next()` 是一个阻塞方法,当消息队列为空时,线程会进入等待状态,不会占用 CPU 资源[^4]。 - **事件驱动**:只有当有新的消息被放入队列时,线程才会被唤醒并继续执行。 #### 2. 死循环卡死的原因 尽管 `Looper.loop()` 内部是一个死循环,但它并不会导致系统卡死,主要原因如下: - **消息队列的阻塞特性**:`MessageQueue.next()` 方法在没有消息时会阻塞当前线程,直到有新消息到来或退出条件满足。这种设计避免了空转导致的 CPU 占用问题[^3]。 - **多线程协作**:虽然主线程运行在 `Looper.loop()` 的死循环中,但 Android 系统会在应用启动时创建额外的 Binder 线程来处理与系统的交互,例如生命周期回调和界面绘制等任务[^1]。 - **高效的消息分发**:`Handler` 和 `Looper` 配合使用,确保每个消息都能被及时处理,而不会阻塞主线程的其他操作[^2]。 #### 3. 主线程的死循环是否消耗 CPU 资源? 在正常情况下,`Looper.loop()` 不会显著消耗 CPU 资源。原因在于: - 当消息队列为空时,`MessageQueue.next()` 方法会让线程进入休眠状态,直到有新消息到来[^4]。 - 一旦有消息需要处理,线程会被唤醒并立即处理该消息,然后再次进入休眠状态。 因此,只要应用没有频繁地向消息队列中插入大量消息,`Looper.loop()` 的死循环对 CPU 的影响可以忽略不计。 #### 4. Activity 生命周期如何实现在死循环体外执行? Activity 的生命周期回调(如 `onCreate()`、`onStart()` 等)实际上是通过 `Handler` 发送消息到主线程的消息队列中实现的。当这些消息被 `Looper` 取出时,它们会被传递给对应的 `Handler`,从而触发相应的生命周期方法[^5]。 例如: ```java // 在某个地方发送消息 handler.post(() -> { activity.onCreate(savedInstanceState); }); ``` 当 `Looper` 从消息队列中取出该消息时,`onCreate()` 方法会被调用,完成初始化操作后,线程继续处理下一个消息。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值