理论

Android IdleHandler

2020-01-19  本文已影响0人  折剑游侠

前面讲Handler的时在MessageQueue源码中看到了IdleHandler的身影

MessageQueue.next()

    Message next() {
        ...
        keep = idler.queueIdle();
        ...
    }

IdleHandler是MessageQueue内部定义的静态接口,官方注释清晰的说明了IdleHandler.queueIdle()是在MessageQueue中没有message,等待更多消息时调用。也就是说IdleHandler是在事件循环空闲时执行的。

    public static interface IdleHandler {
        boolean queueIdle();
    }

Activity、Window、View有说到ui绘制是在onResume()回调方法执行后开启的。

ActivityThread.handleResumeActivity()

    public void handleResumeActivity(...){
    ...
    //回调onResume()
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    ...
    final Activity a = r.activity
    ...
    r.window = r.activity.getWindow();
    View decor = r.window.getDecorView();
    decor.setVisibility(View.INVISIBLE);
    ViewManager wm = a.getWindowManager();
    ...
    //调用到ViewRootImpl.performTraversals()
    r.activity.makeVisible();
    }

onResume()方法回调在ui绘制前就执行了。如此说来在onResume()生命周期之前,ui线程的任何操作都会延迟ui绘制开始执行的时间。可以把一些ui线程执行的耗时逻辑放在IdleHandler中执行,以此来优化页面的启动时间。由于onResume()和performTraversals()本身都是在Looper的事件循环中执行,所以IdleHandler的queueIdle()方法一定会在ui绘制完毕且MessageQueue无消息处理时执行。

使用起来也很简单,实现IdleHandler()接口重写queueIdle()方法就好。

    override fun onResume() {
        super.onResume()

        Looper.myQueue().addIdleHandler {
            //doSomething
            //需注意此处返回值。true会保留,每到空闲都会执行;false执行一次后会remove
            false
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读