美文网首页
IdleHandler学习

IdleHandler学习

作者: 普通的程序员 | 来源:发表于2020-03-14 21:20 被阅读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;   //代表只执行一次
        }  
    });
    ...
    }
    

    相关文章

      网友评论

          本文标题:IdleHandler学习

          本文链接:https://www.haomeiwen.com/subject/kncoshtx.html