當前位置:網站首頁>探索 App 秒開的秘密 —— 啟動性能優化,想提高開發效率的必看

探索 App 秒開的秘密 —— 啟動性能優化,想提高開發效率的必看

2022-01-28 04:02:15 智恩架構師

那麼關鍵的問題是,用戶很可能會因為從啟動窗口到顯示畫面的過程耗時過長而感到厭煩,從而導致用戶沒有來得及等程序啟動完畢就切換到其他 App 了。更嚴重的是,如果啟動時間過長,可能導致程序出現 ANR。我們應該避免出現這兩種糟糕的情况。

啟動方式


Android 應用的啟動方式分為三種:冷啟動、暖啟動、熱啟動,不同的啟動方式决定了應用 UI 對用戶可見所需要花費的時間長短。

顧名思義,冷啟動消耗的時間最長。基於冷啟動方式的優化工作也是最考驗產品用戶體驗的地方。談及優化之前,下面我們來看看這三種啟動方式的應用場景,以及啟動過程中系統都做了些什麼工作。

冷啟動

在安卓系統中,系統為每個運行的應用至少分配一個進程 (多進程應用申請多個進程) 。從進程角度上講,冷啟動就是在啟動應用前,系統中沒有該應用的任何進程信息 (包括 Activity、Service 等) 。

所以,冷啟動產生的場景就很容易理解了,比如設備開機後應用的第一次啟動,系統殺掉應用進程 (如:系統內存吃緊引發的 kill 和用戶主動產生的 kill)後的再次啟動等。那麼自然這種方式下,應用的啟動時間最長,因為相比另外兩種啟動方式,系統和我們的應用要做的工作最多。

應用發生冷啟動時,系統有三件任務要做:

  • 開始加載並啟動應用;

  • 應用啟動後,顯示一個空白的啟動窗口;

  • 創建應用進程信息;

系統創建應用進程後,應用就要做下面這些事情:

  • 初始化應用中的對象(比如 Application 中的工作);

  • 啟動主線程(UI 線程);

  • 創建第一個 Activity;

  • 加載內容視圖(Inflating);

  • 計算視圖在屏幕上的比特置排版(Laying out);

  • 繪制視圖(draw)。

只有當應用完成第一次繪制,系統當前展示的空白背景才會消失,才會被 Activity 的內容視圖替換掉。也就是這個時候,用戶才能和我們的應用開始交互。

下圖展示了冷啟動過程系統和應用的一個工作時間流:

![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUu
aW8vdXBsb2FkX2ltYWdlcy8yMDI2NDI3OC04NTZlMzQ4NDZmMjIxZjFh?x-oss-process=image/format,png)

launch time

這其中有兩個 creation 工作,分別為 Application 和 Activity creation。從圖中看出,他們均在 View 繪制展示之前。所以,在應用自定義的 Application 類和 第一個 Activity 類中,onCreate() 方法做的事情越多,冷啟動消耗的時間越長。

暖啟動

當應用中的 Activities 被銷毀,但在內存中常駐時,應用的啟動方式就會變為暖啟動。

相比冷啟動,暖啟動過程减少了對象初始化、布局加載等工作,啟動時間更短。但啟動時,系統依然會展示一個空白背景,直到第一個 Activity 的內容呈現為止。

熱啟動

相比暖啟動,熱啟動時應用做的工作更少,啟動時間更短。熱啟動產生的場景很多,常見如:用戶使用返回鍵退出應用,然後馬上又重新啟動應用。

啟動時間


從技術角度來說,當用戶點擊桌面圖標開始,系統會立即為這個 App 創建獨立的專屬進程,然後顯示啟動窗口,直到 App 在自己的進程裏面完成了程序的創建以及主線程完成了 Activity 的初始化顯示操作,再然後系統進程就會把啟動窗口替換成 App 的顯示窗口。

start process

上述流程裏面的絕大多數步驟都是由系統控制的,一般來說不會出現什麼問題,可是對於啟動速度,我們能够控制並且需要特別關注的地方主要有三處:

  • Application

Application 的 onCreate 流程,對於大型的 App 來說,通常會在這裏做大量的通用組件的初始化操作。

  • Activity

Activity 的 onCreate 流程,特別是 UI 的布局與渲染操作,如果布局過於複雜很可能導致嚴重的啟動性能問題。

  • 閃屏

目前有部分 APP 會提供自定義的啟動窗口,這裏可以做成品牌宣傳界面或者是給用戶提供一種程序已經啟動的視覺效果。

Display Time

在正式著手解决問題之前,我們需要掌握一套正確測量評估啟動性能的方法。所幸的是,Android 系統有提供一些工具來幫助我們定比特問題。

從 Android 4.4(API 19)開始,Logcat 自動幫我們打印出應用的啟動時間。這個時間值從應用啟動(創建進程)開始計算,到完成視圖的第一次繪制(即 Activity 內容對用戶可見)為止。如:

display time

統計啟動時間

如果是本地調試的話,統計啟動時間還是很簡單的,通過命令行方式即可:

$ adb shell am start -w <包名>/activity

輸出的結果類似於:

$ adb shell am start -W com.jeanboy.app.test/com.jeanboy.app.test.HomeActivity

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.jeanboy.app.test/.HomeActivity }

Status: ok

Activity: com.jeanboy.app.test/.HomeActivity

ThisTime: 496

TotalTime: 496

WaitTime: 503

Complete

  • WaitTime

返回從 startActivity 到應用第一幀完全顯示這段時間。就是總的耗時,包括前一個應用 Activity pause 的時間和新應用啟動的時間;

  • ThisTime

版權聲明
本文為[智恩架構師]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201280402149655.html

隨機推薦