- 方案淺析
- 核心思路
啟動時間的計算蝶涩,無非是end-start
看怎么精確的抓取到這兩個timestamp
這個都很簡單的方法了
在application里加
public static void long START = System.currentTimeMillis();
問題是轰驳,end time要在哪里獲取礁苗?
假設(shè)app的結(jié)構(gòu)如下
application-> splashActivity ->homeActivity
splashActivity做了一些init操作(不包括跳過廣告這樣的業(yè)務(wù)爬凑,只是必須要init一些第三方lib)
homeActivity才是真正業(yè)務(wù)上(有交互)的第一個Activity
以homeActivity真正展示界面為end節(jié)點。
end time要如何獲燃牌痢贰谣?
可能簡單來說娜搂,那么界面展示出來迁霎,就在homeActivity的onResume獲取啊吱抚。
可是onResume就真的是view已經(jīng)show出來了么?
答案是否定的考廉。第一次onResume的時候秘豹,實際上view還沒渲染出來。view.getWidth都拿不到值昌粤。
所以這樣去計算啟動時間既绕,會比實際值小。
所以必須要必須比onResume晚涮坐。
晚多久呢凄贩?
我們都知道view的繪制是放在主線程,那么等view繪制完袱讹,讓主線程通知我們就可以了馒疹。
這個通知的操作巡社,就利用了IdleHandler的特性。
IdleHandler是在整個消息隊列沒有任務(wù)空閑下來就開始工作。
//getMainLooper().getQueue() api 21
Looper.myQueue().addIdleHandler(new IdleHandler() {
@Override
public boolean queueIdle() {
//你要處理的事情
return false;
}
});
有點像Thread的join方法佩脊,Thread-A里調(diào)用了 Thread-B join,
那么Thread-A必須等Thread-B 的join跑完幌墓。
關(guān)于 IdleHandler 在 MessageQueue 與 Looper 和 Handler 的關(guān)系原理源碼分析見
http://www.reibang.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; //代表只執(zhí)行一次
}
});
...
}