本片文章主要介绍一下IdleHandler的基本使用
可以为没有接触过这方面的同学带来一些帮助,文章结尾会提供参考的文章
IdleHandler说白了就是在线程空闲时会执行其中的操作,可以减少我们初始化的时间,
比如我们需要做一些延迟处理,但是每个手机的性能都不一致,那么我们的时间该怎么设置好那
这里就可以使用到我们的IdleHandler,他会在主线程空闲时去执行这个任务,并不会影响其他任务执行
下面介绍一下如何使用
//getMainLooper().myQueue()或者Looper.myQueue()
Looper.myQueue().addIdleHandler(new IdleHandler() {
@Override
public boolean queueIdle() {
//此处添加处理任务
return false;
}
});
queueIdle方法中就是我们处理任务的地方了,在主线程空闲时就会执行这里的代码块了,当然,我们在这里需要注意:在这里尽量不要执行耗时操作
这里的返回值如果是true的话,表示可以反复执行,如果是false的话,表示执行完毕后会移除该idleHandler,只会执行一次
对于多个任务的延迟加载,如果addIdleHandler()调用多次明显不太优雅,而且也不要把所有要延迟的任务都一起放到queueIdle()方法内。根据queueIdle返回true时可以执行多次的特点,可以实现一个任务列表,然后从这个任务列表中取任务执行。
以下是具体代码
import android.os.Looper;
import android.os.MessageQueue;
import java.util.LinkedList;
import java.util.Queue;
public class DelayTaskDispatcher {
private Queue<Task> delayTasks = new LinkedList<>();
private MessageQueue.IdleHandler idleHandler = new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
if (delayTasks.size() > 0) {
Task task = delayTasks.poll();
if (task != null) {
task.run();
}
}
return !delayTasks.isEmpty(); //delayTasks非空时返回ture表示下次继续执行,为空时返回false系统会移除该IdleHandler不再执行
}
};
public DelayTaskDispatcher addTask(Task task) {
delayTasks.add(task);
return this;
}
public void start() {
Looper.myQueue().addIdleHandler(idleHandler);
}
}
我们还可以添加多个任务,在线程空闲时分别执行。
//使用系统Runnable接口自定义Task接口
public interface Task extends Runnable {
}
new DelayTaskDispatcher().addTask(new Task() {
@Override
public void run() {
Log.d(TAG, "DelayTaskDispatcher one task");
}
}).addTask(new Task() {
@Override
public void run() {
Log.d(TAG, "DelayTaskDispatcher two task");
}
}).start();
底层源码这里就不上了
另外,在addIdleHandler时,如果此时消息循环就是在Idle空闲状态,为了让IdleHandler马上执行,可以在其后发送一个空任务。
比如在系统源码 android.app.Instrumentation.java 中就有这种操作:
public class Instrumentation {
public void waitForIdle(Runnable recipient) {
mMessageQueue.addIdleHandler(new Idler(recipient));
mThread.getHandler().post(new EmptyRunnable());
}
private static final class EmptyRunnable implements Runnable {
public void run() {
}
}
}
使用场景
- Activity启动优化:onCreate,onStart,onResume中耗时较短但非必要的代码可以放到IdleHandler中执行,减少启动时间
- 想要在一个View绘制完成之后添加其他依赖于这个View的View,当然这个用View#post()也能实现,区别就是前者会在消息队列空闲时执行
- 发送一个返回true的IdleHandler,在里面让某个View不停闪烁,这样当用户发呆时就可以诱导用户点击这个View,这也是种很酷的操作
本篇参考文章:IdleHandler原理以及延迟初始化方案实现