Android 應(yīng)用啟動優(yōu)化

Android 應(yīng)用啟動優(yōu)化

Android 應(yīng)用的啟動時間長短是衡量應(yīng)用性能的指標(biāo)之一,是用戶對應(yīng)用的第一印象,其重要性不言而喻。

啟動狀態(tài)

應(yīng)用啟動狀態(tài)主要有3種,一般來說冷啟動耗時較長,啟動優(yōu)化主要是優(yōu)化冷啟動時間,這樣做也可以提升溫啟動和熱啟動的性能。

  • 冷啟動

    冷啟動是指應(yīng)用從頭開始啟動:系統(tǒng)進程在冷啟動后才創(chuàng)建應(yīng)用進程。發(fā)生冷啟動的情況包括應(yīng)用

    自設(shè)備啟動后或系統(tǒng)終止應(yīng)用后首次啟動。

  • 熱啟動

    在熱啟動中,系統(tǒng)的所有工作就是將 Activity 帶到前臺。只要應(yīng)用的所有 Activity 仍駐留在內(nèi)存

    中,應(yīng)用就不必重復(fù)執(zhí)行對象初始化、布局加載和繪制。例如按Home鍵

  • 溫啟動

    溫啟動包含了在冷啟動期間發(fā)生的部分操作;同時,它的開銷要比熱啟動高。有許多潛在狀態(tài)可視

    為溫啟動。例如

    • 用戶在退出應(yīng)用后又重新啟動應(yīng)用。進程可能未被銷毀,繼續(xù)運行,但應(yīng)用需要執(zhí)行onCreate() 從頭開始重新創(chuàng)建 Activity。

    • 系統(tǒng)將應(yīng)用從內(nèi)存中釋放,然后用戶又重新啟動它。進程和 Activity 需要重啟,但傳遞到onCreate() 的已保存的實例 state bundle 對于完成此任務(wù)有一定助益。

應(yīng)用啟動流程

啟動流程圖.png
  1. 點擊桌面App圖標(biāo),Launcher進程采用Binder IPC向system_server進程發(fā)起startActivity請求;
  2. system_server進程接收到請求后,向zygote進程發(fā)送創(chuàng)建進程的請求;
  3. Zygote進程fork出新的子進程,即App進程;
  4. App進程,通過Binder IPC向sytem_server進程發(fā)起attachApplication請求;
  5. system_server進程在收到請求后,進行一系列準(zhǔn)備工作后,再通過binder IPC向App進程發(fā)送scheduleLaunchActivity請求;
  6. App進程的binder線程(ApplicationThread)在收到請求后,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息;
  7. 主線程在收到Message后,通過反射機制創(chuàng)建目標(biāo)Activity,并回調(diào)Activity.onCreate()等方法。
  8. 到此,App便正式啟動,開始進入Activity生命周期,執(zhí)行完onCreate/onStart/onResume方法,UI渲染結(jié)束后便可以看到App的主界面。

啟動時間

啟動時間跟手機性能有關(guān),主流旗艦機型啟動時間保持在 2S 內(nèi)為佳

啟動耗時統(tǒng)計

啟動耗時統(tǒng)計有兩種途徑

  • 系統(tǒng)日志統(tǒng)計

    在 Android 4.4(API 級別 19)及更高版本中,logcat 包含一個輸出行,其中包含名為 Displayed 的值。此值代表從啟動進程到在屏幕上完成對應(yīng) Activity 的繪制所用的時間。

日志查看啟動時間.png
  • adb命令統(tǒng)計

    adb shell am start -S -W [packageName]/[activityName]
    
adb統(tǒng)計啟動時間.png

我們一般關(guān)注TotalTime(表示新應(yīng)用啟動的耗時,包括新進程的啟動和Activity的啟動,但不包括前一個應(yīng)用Activity pause的耗時),

啟動狀態(tài)LaunchState有4種情況:

  • LaunchState: COLD (冷啟動)
  • LaunchState: HOT (熱啟動)
  • LaunchState: WARM (溫啟動)
  • LaunchState: UNKNOWN (0) (應(yīng)用在前臺時,調(diào)用adb命令)

問題診斷

  • 使用DebugAPI及profiler 工具

    Android Studio 3.2+ 提供了 profiler 工具(我目前已升級到4.1+ 版本),可查看xxx.trace文件

    1.在application中添加startMethodTracing

        public MyApplication() {
          //相對sd卡路徑,會在sd卡中生成一個app.trace文件(需要sdcard讀寫權(quán)限)。將手機中的trace文件保存至電腦,隨后拖入Android Studio即可。
           //跟蹤方式
            Debug.startMethodTracing("app");
              //采樣方式,間隔1s
              //Debug.startMethodTracingSampling("app",8*1024*1024,1000);
        }
    

    2.在啟動頁的activity中添加stopMethodTracing

    @Override 
    public void onWindowFocusChanged(boolean hasFocus) { 
      super.onWindowFocusChanged(hasFocus); 
      Debug.stopMethodTracing(); 
    }
    

    3.從sd卡保存到電腦并使用Android Studio查看

查看火焰圖.png
查看耗時方法.png

4.優(yōu)先查看耗時較長的方法并分析代碼,遵循性能優(yōu)化方法,例如:

  • 合理的使用異步初始化、延遲初始化、懶加載機制
  • 避免啟動時耗時操作
  • 簡化布局

啟動黑白屏問題

當(dāng)系統(tǒng)加載并啟動 App 時,需要耗費相應(yīng)的時間,這樣會造成用戶會感覺到當(dāng)點擊 App 圖標(biāo)時會有 “延遲” 現(xiàn)象,為了解決這一問題,Google 的做法是在 App 創(chuàng)建的過程中,先展示一個空白頁面,讓用戶體會到點擊圖標(biāo)之后立馬就有響應(yīng)。

如果application或activity啟動的過程太慢,導(dǎo)致系統(tǒng)的BackgroundWindow沒有及時被替換,就會出現(xiàn)啟動時白屏或黑屏的情況(取決于Theme主題是Dark還是Light)。

消除啟動時的黑/白屏問題,大部分App都采用自己在Theme中設(shè)置背景圖的方式來解決。

1.定義主題

<style name="AppTheme.Launcher"> 
        <item name="android:windowBackground">@drawable/bg</item> 
</style> 

2.啟動頁使用主題

<activity android:name=".activity.SplashActivity" 
          android:screenOrientation="portrait" 
          android:theme="@style/AppTheme.Launcher"> 
  <intent-filter> 
    <action android:name="android.intent.action.MAIN" /> 
    <category android:name="android.intent.category.LAUNCHER" /> 
  </intent-filter> 
</activity>

3.啟動頁還原為應(yīng)用主題

@Override 
protected void onCreate(Bundle savedInstanceState) { 
//替換為原來的主題,在onCreate之前調(diào)用 
  setTheme(R.style.AppTheme); 
  super.onCreate(savedInstanceState); 
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容