android idle监听,Android IdleHandler 原理浅析

问:什么是 IdleHandler?有什么用?怎么用?

答:IdleHandler 可以用来提升性能,主要用在我们希望能够在当前线程消息队列空闲时做些事情(譬如 UI 线程在显示完成后,如果线程空闲我们就可以提前准备其他内容)的情况下,不过最好不要做耗时操作。具体用法如下。

//getMainLooper().myQueue()或者Looper.myQueue()

Looper.myQueue().addIdleHandler(new IdleHandler() {

@Override

public boolean queueIdle() {

//你要处理的事情

return false;

}

});

关于 IdleHandler 在 MessageQueue 与 Looper 和 Handler 的关系原理源码分析如下:

/**

* 获取当前线程队列使用Looper.myQueue(),获取主线程队列可用getMainLooper().myQueue()

*/

public final class MessageQueue {

......

/**

* 当前队列将进入阻塞等待消息时调用该接口回调,即队列空闲

*/

public static interface IdleHandler {

/**

* 返回true就是单次回调后不删除,下次进入空闲时继续回调该方法,false只回调单次。

*/

boolean queueIdle();

}

/**

*

This method is safe to call from any thread.

* 判断当前队列是不是空闲的,辅助方法

*/

public boolean isIdle() {

synchronized (this) {

final long now = SystemClock.uptimeMillis();

return mMessages == null || now < mMessages.when;

}

}

/**

*

This method is safe to call from any thread.

* 添加一个IdleHandler到队列,如果IdleHandler接口方法返回false则执行完会自动删除,

* 否则需要手动removeIdleHandler。

*/

public void addIdleHandler(@NonNull IdleHandler handler) {

if (handler == null) {

throw new NullPointerException("Can't add a null IdleHandler");

}

synchronized (this) {

mIdleHandlers.add(handler);

}

}

/**

*

This method is safe to call from any thread.

* 删除一个之前添加的 IdleHandler。

*/

public void removeIdleHandler(@NonNull IdleHandler handler) {

synchronized (this) {

mIdleHandlers.remove(handler);

}

}

......

//Looper的prepare()方法会通过ThreadLocal准备当前线程的MessageQueue实例,

//然后在loop()方法中死循环调用当前队列的next()方法获取Message。

Message next() {

......

for (;;) {

......

nativePollOnce(ptr, nextPollTimeoutMillis);

synchronized (this) {

......

//把通过addIdleHandler添加的IdleHandler转成数组存起来在mPendingIdleHandlers中

// If first time idle, then get the number of idlers to run.

// Idle handles only run if the queue is empty or if the first message

// in the queue (possibly a barrier) is due to be handled in the future.

if (pendingIdleHandlerCount < 0

&& (mMessages == null || now < mMessages.when)) {

pendingIdleHandlerCount = mIdleHandlers.size();

}

if (pendingIdleHandlerCount <= 0) {

// No idle handlers to run. Loop and wait some more.

mBlocked = true;

continue;

}

if (mPendingIdleHandlers == null) {

mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];

}

mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);

}

// Run the idle handlers.

// We only ever reach this code block during the first iteration.

//循环遍历所有IdleHandler

for (int i = 0; i < pendingIdleHandlerCount; i++) {

final IdleHandler idler = mPendingIdleHandlers[i];

mPendingIdleHandlers[i] = null; // release the reference to the handler

boolean keep = false;

try {

//调用IdleHandler接口的queueIdle方法并获取返回值。

keep = idler.queueIdle();

} catch (Throwable t) {

Log.wtf(TAG, "IdleHandler threw exception", t);

}

//如果IdleHandler接口的queueIdle方法返回false说明只执行一次需要删除。

if (!keep) {

synchronized (this) {

mIdleHandlers.remove(idler);

}

}

}

......

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值