自由屋推书网—热门的小说推荐平台!

你的位置: 首页 > Andriod

Android IdleHandler基本使用及应用案例详解

2022-10-12 09:35:21

IdleHandler基本使用

IdleHandler原型

public static interface IdleHandler {
boolean queueIdle();
}

不看源码直接上结论,Android应用的运行都是靠着一条条Message入队、出队、执行实现,当应用主线程的消息队列空闲的时候(消息队列没有消息或下一次消息执行的时间还未到),就会尝试去执行IdleHandler集合。

其中:IdleHandlerqueueIdle方法的返回值如果为false,那么IdleHandler执行完之后就会被移除,也就是说只会被执行一次;如果返回值为true,不会被移除且可以被执行多次。

所以我们就可以向消息队列的IdleHandler集合中插具体的IdleHandler在应用主线程空闲的时候执行一些操作,基本的使用如下:

Looper.getMainLooper().queue.addIdleHandler {
true
}

案例1:执行GC

大家都知道,不能随便在主线程执行GC,否则很容易造成卡顿,但是我们可以在主线程空闲的时候去执行GC,这个时候就可以利用IdleHandler,Android源码中就有如下使用:

#ActivityThread
void scheduleGcIdler() {
Looper.myQueue().addIdleHandler(mGcIdler);
}

final class GcIdler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
doGcIfNeeded();
}
}

void doGcIfNeeded(String reason) {
 //执行GC
 BinderInternal.forceGc(reason);
}

这样既可以满足gc回收对象的需要,又不会影响主线程中其他任务的执行

案例2:粗估Activity界面渲染时间

我们首先要明确界面渲染流程是发生在Activity的onResume生命周期,往主线程消息队列添加消息屏障(之后添加的Message只能执行异步类型的),然后发送界面渲染异步Message,等到界面渲染完成后才会从消息队列移除屏障消息,这个时候才能正常执行其他Message。

参考下滴滴的DoKit开源库:

我们现在onResume方法中记录界面开始渲染时间,添加一个IdleHandler,这个会在界面渲染相关Message执行完毕后再执行它,所以就可以简单的估算出界面渲染时长。

案例3:App大图监测

常见的大图监控方法都是将ImageView替换成自定义ImageView,然后重写设置图片的方法,比如setImageBitmap()等等,在方法中计算下图片的宽高是否超过ImageView的宽高,是就弹出一个弹窗提醒开发者,一般在Debug环境下执行这种检测。

Debug环境下开启大图检测,一般为了避免影响主线程其他任务执行,都会添加一个IdleHandler等主线程空闲了再去执行大图检测:

案例4:延迟启动初始化任务

一般我们都在ApplicationonCreate方法中执行任务(比如第三方SDK)的初始化,可是如果执行的初始化任务过多就会增加启动耗时,给用户带来较差体验。

而且有的任务并不是一定就需要在ApplicationonCreate就必须要执行,可以延迟初始化,减少应用启动耗时,这个时候就可以把相关延迟任务添加到一个Idlehandler中去执行。

编辑推荐

热门小说