如何計算 App 的啟動時間

來源:互聯網
上載者:User

標籤:tab   需要   tco   執行   開發   android中   rtl   沒有   分表   

應用啟動情境

事實上 Android 中一個 App 的啟動時間可以準確計算的.但是要分情境.也就是說要分開遊戲和應用. 大家都知道,在Android中,遊戲開發和應用開發是兩碼事.所以我們需要分開來說.

1.1 應用啟動

我們平時在寫應用的時候,一般會指定一個 mainActivity ,使用者在案頭上點擊這個 Activity 的時候,系統會直接起這個 Activity. 我們知道 Activity 在啟動的時候會走 onCreate/onStart/onResume .這幾個回呼函數.

許多書裡講過,當執行完 onResume 函數之後,應用就顯示出來了…其實這是一種不準確的說法,因為從系統層面來看,一個 Activity 走完 onCreate/onStart/onResume 這幾個生命週期之後,只是完成了應用自身的一些配置,比如 window 的一些屬性的設定/ View 樹的建立(只是建立,並沒有顯示,也就是說只是調用了 inflate 而已) . 後面 ViewRootImpl 還會調用兩次performTraversals ,初始化 Egl 以及 measure/layout/draw. 等.
所以我們定義一個 Android 應用的啟動時間, 肯定不能在 Activity 的回呼函數上下手.而是以使用者在手機螢幕上看到你在 onCreate 的 setContentView 中設定的 layout 完全顯示為準,也就是我們常說的應用第一幀.

上面扯得有點遠,不感興趣的話可以不看,下面直接說方法.
題主說的 adb shell am start -w packagename/activity,是可以完全應用的啟動時間的.不過也要分情境.

1.2 應用第一次啟動

也就是我們常說的冷啟動,這時候你的應用程式的進程是沒有建立的. 這也是大部分應用的使用情境.使用者在案頭上點擊你應用的 icon 之後,首先要建立進程,然後才啟動 MainActivity.
這時候adb shell am start -w packagename/MainActivity 返回的結果,就是標準的應用程式的啟動時間(注意 Android 5.0 之前的手機是沒有 WaitTime 這個值的):

1
? adb shell am start -W com.meizu.media.painter/com.meizu.media.painter.PainterMainActivityStarting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.meizu.media.painter/.PainterMainActivity }Status: okActivity: com.meizu.media.painter/.PainterMainActivityThisTime: 355TotalTime: 355WaitTime: 365Complete

總共返回了三個結果,我們以 WaitTime 為準. 

關於ThisTime/TotalTime/WaitTime的區別,下面是其解釋:

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

  • startTime記錄的剛準備調用startActivityAndWait()的時間點
  • endTime記錄的是startActivityAndWait()函數調用返回的時間點
  • WaitTime = startActivityAndWait()調用耗時。 

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

我們來解釋下代碼裡curTime、displayStartTime、mLaunchStartTime三個時間變數.

  • curTime表示該函數調用的時間點.
  • displayStartTime表示一連串啟動Activity中的最後一個Activity的啟動時間點.
  • mLaunchStartTime表示一連串啟動Activity中第一個Activity的啟動時間點. 

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

在上面的圖中,我用①②③分別標註了三個時間段,在這三個時間段內分別幹了什麼事呢? 

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

看到這裡應該清楚 ThisTime、TotalTime、WaitTime 三個時間的關係了吧:

  • WaitTime 就是總的耗時,包括前一個應用 Activity pause 的時間和新應用啟動的時間;
  • ThisTime 表示一連串啟動 Activity 的最後一個 Activity 的啟動耗時;
  • TotalTime 表示新應用啟動的耗時,包括新進程的啟動和 Activity 的啟動,但不包括前

一個應用 Activity pause 的耗時。也就是說,開發人員一般只要關心 TotalTime 即可,這個時間才是自己應用真正啟動的耗時。 

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

最後再說下系統根據什麼來判斷應用啟動結束。我們知道應用啟動包括進程啟動、走 Activity生命週期 onCreate/onResume 等。在第一次 onResume 時添加視窗到WMS中,然後measure/layout/draw,視窗繪製完成後通知 WMS,WMS 在合適的時機控制介面開始顯示(夾雜了介面切換動畫邏輯)。記住是視窗介面顯示出來後,WMS 才調用reportLaunchTimeLocked() 通知 AMS Activity 啟動完成。 

最後總結一下,如果只關心某個應用自身啟動耗時,參考TotalTime;如果關心系統啟動應用耗時,參考WaitTime;如果關心應用有介面Activity啟動耗時,參考ThisTime。

如何計算 App 的啟動時間

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.