IdleHandler学习

2020-03-14  本文已影响0人  普通的程序员

启动时间的计算,无非是end-start
看怎么精确的抓取到这两个timestamp
这个都很简单的方法了
在application里加

public static void long START  = System.currentTimeMillis();

问题是,end time要在哪里获取?

假设app的结构如下

application-> splashActivity ->homeActivity

splashActivity做了一些init操作(不包括跳过广告这样的业务,只是必须要init一些第三方lib)

homeActivity才是真正业务上(有交互)的第一个Activity

以homeActivity真正展示界面为end节点。

end time要如何获取?

可能简单来说,那么界面展示出来,就在homeActivity的onResume获取啊。

可是onResume就真的是view已经show出来了么?

答案是否定的。第一次onResume的时候,实际上view还没渲染出来。view.getWidth都拿不到值。

所以这样去计算启动时间,会比实际值小。

所以必须要必须比onResume晚。

晚多久呢?

我们都知道view的绘制是放在主线程,那么等view绘制完,让主线程通知我们就可以了。

这个通知的操作,就利用了IdleHandler的特性。
IdleHandler是在整个消息队列没有任务空闲下来就开始工作。

//getMainLooper().getQueue() api 21
Looper.myQueue().addIdleHandler(new IdleHandler() {  
    @Override  
    public boolean queueIdle() {  
        //你要处理的事情
        return false;    
    }  
});

有点像Thread的join方法,Thread-A里调用了 Thread-B join,
那么Thread-A必须等Thread-B 的join跑完。

关于 IdleHandler 在 MessageQueue 与 Looper 和 Handler 的关系原理源码分析见
https://www.jianshu.com/p/a1d945c4f5a6

那么end time的获取,就放在idleHandler里。
在onCreate方法里加入

@Override
public void onCreate(){
...
Looper.myQueue().addIdleHandler(new IdleHandler() {  
    @Override  
    public boolean queueIdle() {  
        long end = System.currentTimeMillis();
        long duration = end -  Application.START;
        // 如果 是测量某个activity的完全启动,这个START时间就放在该activity的全局变量里
        return false;   //代表只执行一次
    }  
});
...
}
上一篇 下一篇

猜你喜欢

热点阅读