IdleHandler 的原理分析和妙用,历经30天

本文深入探讨了Android中的IdleHandler机制,揭示了其在消息队列空闲时执行任务的原理。通过分析MessageQueue的next()方法,解释了IdleHandler如何在没有消息或者延迟消息未触发时被调用。文章还介绍了系统如何在Activity的onResume之后利用IdleHandler进行资源回收,并指出在长时间无操作时,系统如何确保界面关闭。此外,文章讨论了IdleHandler在应用启动时优化性能和在View绘制完成后的应用场景,并提及LeakCanary库如何利用此机制。
摘要由CSDN通过智能技术生成

return;

}

···

msg.recycleUnchecked();

}

}

可以看到,loop 方法中存在一个for(;;)死循环,如果该方法中 queue.next()方法返回 null ,那么直接 return 退出整个死循环,整个ActivityThread.main()方法也就结束了,整个程序也就退出了。但是我们的程序肯定是一直在运行的,也就是说 queue.next()方法中一直有消息,但是如果一段时间没有操作了,整个程序也就没有执行的消息了,那为什么程序还能一直运行呢,所以问题肯定就在 queue.next()这个方法中。

该方法中也有一个 for(;;)死循环,里面有一个关键方法 nativePollOnce

@UnsupportedAppUsage

Message next() {

// Return here if the message loop has already quit and been disposed.

// This can happen if the application tries to restart a looper after quit

// which is not supported.

···

int nextPollTimeoutMillis = 0;

for (;😉 {

if (nextPollTimeoutMillis != 0) {

Binder.flushPendingCommands();

}

···

nativePollOnce(ptr, nextPollTimeoutMillis); //没有消息,阻塞等待

···

}

}

该方法在 nextPollTimeoutMillis = -1的时候就阻塞等待,直到下一条消息可用为止。否则就继续向下执行。那我们再看看是在哪里唤醒的呢?是在消息入队最终执行的方法 enqueueMessage 中:

boolean enqueueMessage(Message msg, long when) {

···

// We can assume mPtr != 0 because mQuitting is false.

if (needWake) {

nativeWake(mPtr);

}

}

return true;

}

在 nativeWake 方法中进行唤醒,就是唤醒上面的那个地方,没有消息的时候,这里就处于阻塞状态。

这样我们把消息处理机制的整个逻辑大概梳理了一下,为什么需要理清呢,因为 IdleHandler 是在消息队列没有消息或者是在有暂时不需要处理的消息(延迟消息),就是说这个时候是空闲的,进行 IdleHandler 进行处理的。所以我们可以猜测 IdleHandler 应该也在 next 方法中进行触发它的方法。事实也确实如此:

Message next() {

for (;😉 {

synchronized (this) {

// 此处为正常消息队列的处理

if (mQuitt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值