Android 項目優化(五):應用啓動優化

介紹了前面的優化的方案後,這裏咱們在針對應用的啓動優化作一下講解和說明。html

1、App啓動概述

一個應用App的啓動速度可以影響用戶的首次體驗,啓動速度較慢(感官上)的應用可能致使用戶再次開啓App的意圖降低,或者卸載放棄該應用程序。android

應用程序啓動有主要分爲兩種狀態,每種狀態都會影響應用程序對用戶可見所需的時間:冷啓動,熱啓動。shell

  • 冷啓動:冷啓動表示用戶首次打開應用,這時進程還沒建立,包含了Application建立的過程。冷啓動時間指從第一次用戶點擊Launcher中的應用圖標開始,到首頁內容所有展現出來。
  • 熱啓動:熱啓動表示用戶在首頁按了返回,首頁Activity已經Destroy,不過Application仍在內存中存在,對應的進程並無被殺掉,不包含Application建立過程。熱啓動時間指在Application仍然存在的狀況下,從用戶點擊桌面圖標,到首頁內容所有展現出來。

注:冷啓動、熱啓動不是官方的定義,而是咱們基於用戶的角度考慮的定義。網絡

在冷啓動開始時,系統有三個任務。這些任務是:佈局

  1. 加載並啓動應用程序。
  2. 啓動後當即顯示應用程序空白的啓動窗口。
  3. 建立應用程序進程。

一旦系統建立應用程序進程,應用程序進程就會負責下一階段。這些階段是:性能

  1. 建立App對象
  2. 啓動主線程(main thread)
  3. 建立應用入口的Activity對象
  4. 填充加載佈局Views
  5. 在屏幕上執行View的繪製過程.measure -> layout -> draw

應用程序進程完成第一次繪製後,系統進程會交換當前顯示的背景窗口,將其替換爲主Activity。此時,用戶能夠開始使用該應用程序。優化

這裏咱們建議始終根據冷啓動的假設進行優化。這樣作也能夠改善熱啓動的性能。ui

2、冷啓動視覺效果優化

上面咱們說了,冷啓動的階段執行的操做爲:spa

  1. 加載並啓動應用程序
  2. 啓動後當即顯示應用程序空白的啓動窗口
  3. 建立應用程序進程

如今 App 應用啓動都會先進入一個閃屏頁(LaunchActivity) 來展現應用信息。線程

系統默認會在啓動應用程序的時候啓動空白窗口 ,直到 App 應用程序的入口Activity建立成功,視圖繪製完畢。可是存在的問題就是在進入閃屏頁的時候,會有2秒左右的白屏/灰屏的界面。

爲了更順滑無縫銜接咱們的閃屏頁,能夠在啓動 Activity 的 Theme中設置閃屏頁圖片,這樣啓動窗口的圖片就會是閃屏頁圖片,而不是白屏。配置代碼以下:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/lunch</item>  //閃屏頁圖片
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">false</item><!--顯示虛擬按鍵,並騰出空間-->
</style>

這樣設置的話,就會在冷啓動的時候,展現閃屏頁的圖片,等App進程初始化加載入口 Activity (也是閃屏頁) 就能夠無縫銜接。

其實這種方式並無真正的加速應用進程的啓動速度,而只是經過用戶視覺效果帶來的優化體驗。

備註:上面的方案適用於閃屏頁爲整張圖片爲閃屏內容(閃屏頁圖片推薦.9格式,防止拉伸失真)。不適用於閃屏頁爲多個元素混合的。後者推薦參考 Android 項目優化(二):啓動頁面優化

 

3、App冷啓動耗時統計

App冷啓動耗時統計方式主要是:adb 命令統計、系統日誌統計。

1. adb 命令統計

adb命令 : adb shell am start -S -W 包名/啓動類的全限定名 , -S 表示重啓當前應用。示例以下:

C:\Android\Demo>adb shell am start -S -W com.example.moneyqian.demo/com.example.moneyqian.demo.MainActivity
Stopping: com.example.moneyqian.demo
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.moneyqian.demo/.MainActivity }
Status: ok
Activity: com.example.moneyqian.demo/.MainActivity
ThisTime: 2247
TotalTime: 2247
WaitTime: 2278
Complete

 

ThisTime : 最後一個 Activity 的啓動耗時(例如從 LaunchActivity - >MainActivity「adb命令輸入的Activity」 , 只統計 MainActivity 的啓動耗時)
TotalTime : 啓動一連串的 Activity 總耗時.(有幾個Activity 就統計幾個)
WaitTime : 應用進程的建立過程 + TotalTime .

總結一下 : 若是須要統計從點擊桌面圖標到 Activity 啓動完畢,能夠用WaitTime做爲標準,可是系統的啓動時間優化不了,因此優化冷啓動咱們只要在乎 ThisTime 便可。

2. 系統日誌統計

根據系統日誌來統計啓動耗時,在Android Studio中查找已用時間,必須在logcat視圖中禁用過濾器(No Filters)。由於這個是系統的日誌輸出,而不是應用程序的。

好比咱們能夠經過過濾displayed輸出的啓動日誌. 示例以下:

4、冷啓動 Application 優化

咱們知道有不少第三方組件(包括App應用自己)都在 Application 中完成初始化操做。可是在 Application 中完成繁重的初始化操做和複雜的邏輯就會影響到應用的啓動性能。

經過分析一下,咱們能夠知道仍是有機會優化這些工做以實現冷啓動的性能改進的,分析後發現影響冷啓動時間的常見問題以下:

  • 複雜繁瑣的佈局初始化
  • 阻塞主線程 UI 繪製的操做,如 I/O 讀寫或者是網絡訪問.
  • 其它佔用主線程的操做

咱們能夠根據這些組件的輕重緩急之分,對初始化作一下分類 :

  • 必要的組件必定要在主線程中當即初始化(入口 Activity 可能當即會用到)
  • 組件必定要在主線程中初始化,可是能夠延遲初始化。
  • 組件能夠在子線程中初始化。

在進行優化的時候,須要注意如下幾種狀況:

  • 放在子線程的組件初始化建議延遲初始化,這樣就能夠了解是否會對項目形成影響! 
  • 將須要在主線程中初始化可是能夠不用當即完成的動做延遲加載(初始化放在 Application 中統一管理爲妙,不建議放在Activity裏面)
  • 能夠嘗試將常見的組件庫,例如 Bugly,x5內核初始化,SP的讀寫,友盟等組件放到子線程中初始化。(子線程初始化不能影響到組件的使用)

在優化好啓動時間後,咱們就能夠在針對閃屏頁的時間,進行調整優化,具體公式爲:

閃屏頁展現總時間 = 組件初始化時間 + 剩餘展現時間
相關文章
相關標籤/搜索