1. 程式人生 > >APP的啟動時間計算

APP的啟動時間計算

本文轉自https://juejin.im/entry/5aa24615f265da237b21aede

➜ adb shell am start -W com.media.painter/com.media.painter.PainterMainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.media.painter/.PainterMainActivity }
Status: ok
Activity: com.media.painter/.PainterMainActivity
ThisTime: 355
TotalTime: 355
WaitTime: 365
Complete

“adb shell am start -W ”的實現在 frameworks\base\cmds\am\src\com\android\commands\am\Am.java 檔案中。其實就是跨Binder呼叫ActivityManagerService.startActivityAndWait() 介面(後面將ActivityManagerService簡稱為AMS),這個介面返回的結果包含上面列印的ThisTime、TotalTime時間.

WaitTime = endTime - startTime。

  1. startTime:記錄剛準備呼叫startActivityAndWait()的時間點;
  2. endTime:記錄startActivityAndWait()函式呼叫返回的時間點
  3. WaitTime:startActivityAndWait()呼叫耗時

ThisTime、TotalTime 的計算在 frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java 檔案的 reportLaunchTimeLocked() 函式中。

curTime/displayStartTime/mLaunchStartTime

程式碼裡curTime、displayStartTime、mLaunchStartTime三個時間變數:

  1. curTime表示該函式呼叫的時間點
  2. displayStartTime表示一連串啟動Activity中的最後一個Activity的啟動時間點
  3. mLaunchStartTime表示一連串啟動Activity中第一個Activity的啟動時間點

正常情況下點選桌面圖示只啟動一個有介面的 Activity,此時 displayStartTime 與mLaunchStartTime 便指向同一時間點,此時 ThisTime=TotalTime。另一種情況是點選桌面圖示應用會先啟動一個無介面的 Activity 做邏輯處理,接著又啟動一個有介面的Activity,在這種啟動一連串 Activity 的情況下(知乎的啟動就是屬於這種情況),displayStartTime 便指向最後一個 Activity 的開始啟動時間點,mLaunchStartTime 指向第一個無介面Activity的開始啟動時間點,此時 ThisTime!=TotalTime。這兩種情況如下圖:

curTime/displayStartTime/mLaunchStartTime

①②③分別標註了三個時間段:

  1. 在第①個時間段內,AMS 建立 ActivityRecord 記錄塊和選擇合理的 Task、將當前Resume 的 Activity 進行 pause;
  2. 在第②個時間段內,啟動程序、呼叫無介面 Activity 的 onCreate() 等、 pause/finish 無介面的 Activity;
  3. 在第③個時間段內,呼叫有介面 Activity 的 onCreate、onResume

ThisTime、TotalTime、WaitTime 三個時間的關係:

  1. WaitTime 就是總的耗時,包括前一個應用 Activity pause 的時間和新應用啟動的時間;
  2. ThisTime 表示一連串啟動 Activity 的最後一個 Activity 的啟動耗時;
  3. TotalTime 表示新應用啟動的耗時,包括新程序的啟動和 Activity 的啟動,但不包括前一個應用 Activity pause 的耗時。也就是說,開發者一般只要關心 TotalTime 即可,這個時間才是自己應用真正啟動的耗時。

Event log中 TAG=am_activity_launch_time 中的兩個值分別表示 ThisTime、TotalTime,跟通過 “adb shell am start -W ” 得到的值是一致的。

例:

am_activity_launch_time: [0,267963642,com.android.settings/.FallbackHome,597,597]
am_activity_launch_time: [0,18472980,com.android.launcher/com.android.launcher2.Launcher,1351,1351]
am_activity_launch_time: [0,226256788,com.android.settings/.Settings,659,659]
am_activity_launch_time: [0,176144538,com.android.settings/.Settings$ConnectedDeviceDashboardActivity,1024,1024]
am_activity_launch_time: [0,199665464,com.android.settings/.deviceinfo.UsbModeChooserActivity,390,390]
am_activity_launch_time: [0,18056767,com.android.settings/.deviceinfo.UsbModeChooserActivity,280,280]