當前位置:網站首頁>探索 App 秒開的秘密 —— 啟動性能優化,想提高開發效率的必看
探索 App 秒開的秘密 —— 啟動性能優化,想提高開發效率的必看
2022-01-28 04:02:15 【智恩架構師】
那麼關鍵的問題是,用戶很可能會因為從啟動窗口到顯示畫面的過程耗時過長而感到厭煩,從而導致用戶沒有來得及等程序啟動完畢就切換到其他 App 了。更嚴重的是,如果啟動時間過長,可能導致程序出現 ANR。我們應該避免出現這兩種糟糕的情况。
Android 應用的啟動方式分為三種:冷啟動、暖啟動、熱啟動,不同的啟動方式决定了應用 UI 對用戶可見所需要花費的時間長短。
顧名思義,冷啟動消耗的時間最長。基於冷啟動方式的優化工作也是最考驗產品用戶體驗的地方。談及優化之前,下面我們來看看這三種啟動方式的應用場景,以及啟動過程中系統都做了些什麼工作。
冷啟動
在安卓系統中,系統為每個運行的應用至少分配一個進程 (多進程應用申請多個進程) 。從進程角度上講,冷啟動就是在啟動應用前,系統中沒有該應用的任何進程信息 (包括 Activity、Service 等) 。
所以,冷啟動產生的場景就很容易理解了,比如設備開機後應用的第一次啟動,系統殺掉應用進程 (如:系統內存吃緊引發的 kill 和用戶主動產生的 kill)後的再次啟動等。那麼自然這種方式下,應用的啟動時間最長,因為相比另外兩種啟動方式,系統和我們的應用要做的工作最多。
應用發生冷啟動時,系統有三件任務要做:
-
開始加載並啟動應用;
-
應用啟動後,顯示一個空白的啟動窗口;
-
創建應用進程信息;
系統創建應用進程後,應用就要做下面這些事情:
-
初始化應用中的對象(比如 Application 中的工作);
-
啟動主線程(UI 線程);
-
創建第一個 Activity;
-
加載內容視圖(Inflating);
-
計算視圖在屏幕上的比特置排版(Laying out);
-
繪制視圖(draw)。
只有當應用完成第一次繪制,系統當前展示的空白背景才會消失,才會被 Activity 的內容視圖替換掉。也就是這個時候,用戶才能和我們的應用開始交互。
下圖展示了冷啟動過程系統和應用的一個工作時間流:

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
邊欄推薦
猜你喜歡
隨機推薦
- uniapp上傳圖片及組件傳值
- 瑞利年金險資金保障安全嗎?收益高不高啊?
- 華為手機USB連不上電腦的解决方法
- Flutter 2,移動金融應用開發
- 關於st25系列NFC標簽簡單介紹及st25TV系列用於門禁讀取時的注意事項總結
- 關於用ffmpeg轉手機視頻發現視頻長寬倒了的問題
- 函數 / 類模板--模板2
- 數組中的第k個最大的元素--優先級隊列、排序、堆、排序
- 單片機實例27——ADC0809A/D轉換器基本應用技術(硬件電路圖+匯編程序+C語言程序)
- Collection集合的學習
- 一場面試結束,某度員工從事Android 5年為何還是初級工程師?
- 3本書閱讀筆記【人月神話-Go語言實戰-研發能力持續成長路線】01
- PHP垃圾回收機制
- 【電子技術】什麼是LFSR?
- 死鎖?如何定比特到死鎖?如何修複死鎖?(jps和jstack兩個工具)
- 快樂寒假 22/01/20
- image
- 噴程序員?SURE?
- LDO分壓電阻計算小工具
- 面試之求一串字符串中每個字符的出現次數
- 【ISO15765_UDS&OBD診斷】-01-概述
- 【Mysql上分之路】第九篇:Mysql存儲引擎
- RHCE 第一次作業
- 2021.10.16我的第一篇博客:一切皆有可能!
- CTA-敏感行為-讀取IMEI
- 面試被問怎麼排查平時遇到的系統CPU飆高和頻繁GC,該怎麼回答?
- nuxt項目總結-綜合
- 自然語言處理學習筆記(一)
- C語言第一課
- 各比特大佬,Spark的重點難點系列暫時更新完畢
- 基於 esbuild 的 universal bundler 設計
- XCTFre逆向(四):insanity
- 理解什麼是真正的並發數
- JVM腦圖
- 【Pytorch(四)】學習如何使用 PyTorch 讀取並處理數據集
- 函數棧幀的創建與銷毀
- 構建神經網絡- 手寫字體識別案例
- 多模態生成模型ERNIE-VILG
- kotlin不容忽視的小細節
- 備戰一年,終於斬獲騰訊T3,我堅信成功是可以複制的