這多是最好的性能優化教程(二)

前言

上篇寫了 ArrayMap 和 UI 性能優化,這篇我想和你們聊聊每一個人都關心的 APP 啓動,參見 Android 性能優化典範android

正文

提升 APP 的啓動速度對咱們意義深遠,很顯然,APP 的啓動時間越短,使用它的用戶越有耐心等待打開這個 APP 進行使用。反之,啓動時間太長,用戶則有可能還沒等到 APP 打開就已經切換到其餘 APP 了。性能優化

程序啓動過程當中那些複雜錯誤的操做頗有可能致使嚴重的性能問題。Android 系統會根據用戶的操做行爲調整程序的顯示策略,用來提升程序的顯示性能。例如,一旦用戶點擊桌面圖標,Android 系統會當即顯示一個啓動窗口,這個窗口會一直保持顯示直到畫面中的元素成功加載並繪製完第一幀。這種行爲常見於程序的冷啓動,或者程序的熱啓動場景(程序從後臺被喚起或者從其餘 APP 界面切換回來)。網絡

那麼關鍵的問題是,用戶極可能會由於從啓動窗口到顯示畫面的過程耗時過長而感到厭煩,從而致使用戶沒有來得及等程序啓動完畢就切換到其餘 APP 了。更嚴重的是,若是啓動時間過長,可能致使程序出現 ANR。咱們應該避免出現這兩種糟糕的狀況異步

從技術角度來講,當用戶點擊桌面圖標開始,系統會當即爲這個 APP 建立獨立的專屬進程,而後顯示啓動窗口,直到 APP 在本身的進程裏面完成了程序的建立以及主線程完成了 Activity 的初始化顯示操做,再而後系統進程就會把啓動窗口替換成 APP 的顯示窗口。函數

上述流程裏面的絕大多數步驟都是由系統控制的,通常來講不會出現什麼問題,但是對於啓動速度,咱們可以控制而且須要特別關注的地方主要有三處:工具

  • Activity 的 onCreate 流程,特別是UI的佈局與渲染操做,若是佈局過於複雜極可能致使嚴重的啓動性能問題。
  • Application 的 onCreate 流程,對於大型的 APP 來講,一般會在這裏作大量的通用組件的初始化操做。
  • 目前有部分 APP 會提供自定義的啓動窗口,這裏能夠作成品牌宣傳界面或者是給用戶提供一種程序已經啓動的視覺效果。

在正式着手解決問題以前,咱們須要掌握一套正確測量評估啓動性能的方法。所幸的是,Android 系統有提供一些工具來幫助咱們定位問題。佈局

有趣的啓動時長定位

display time

從 Android KitKat 版本開始,Logcat 中會輸出從程序啓動到某個 Activity 顯示到畫面上所花費的時間。這個方法比較適合測量程序的啓動時間。
性能

reportFullyDrawn()

咱們一般來講會使用異步懶加載的方式來提高程序畫面的顯示速度,這一般會致使的一個問題是,程序畫面已經顯示,但是內容卻還在加載中。爲了衡量這些異步加載資源所耗費的時間,咱們能夠在異步加載完畢以後調用 activity.reportFullyDrawn() 方法來告訴系統此時的狀態,以便獲取整個加載的耗時。
優化

Method Tracing

前面兩個方法提供了啓動耗時的總時間,但是卻沒法提供具體的耗時細節。爲了獲取具體的耗時分佈狀況,咱們可使用 Method Tracing 工具來進行詳細的測量。spa

Systrace

咱們能夠在 onCreate() 方法裏面添加 trace.beginSection()trace.endSection() 方法來聲明須要跟蹤的起止位置,系統會幫忙統計中間經歷過的函數調用耗時,並輸出報表。

若是優化 APP 啓動速度?

提高 Activity 的建立速度

提高 Activity 的建立速度是優化 APP 啓動速度的首要關注目標。從桌面點擊 APP 圖標啓動應用開始,程序會顯示一個啓動窗口等待 Activity 的建立加載完畢再進行顯示。在 Activity 的建立加載過程當中,會執行不少的操做,例如設置頁面的主題,初始化頁面的佈局,加載圖片,獲取網絡數據,讀寫 Preference 等等。


上述操做的任何一個環節出現性能問題均可能致使畫面不能及時顯示,影響了程序的啓動速度。上一個段落咱們介紹了使用 Method Tracing 來發現那些耗時佔比相對較多的方法。假設咱們發現某個方法執行時間過長,接下去就可使用 Systrace 來幫忙定位究竟是什麼緣由致使那個方法執行時間過長。

除了使用工具進行具體定位分析性能問題以外,如下兩點經驗能夠幫助咱們對 Activity 啓動作性能優化:

  • 優化佈局耗時:一個佈局層級越深,裏面包含須要加載的元素越多,就會耗費更多的初始化時間。關於佈局性能的優化,這裏就不展開描述了!
  • 異步延遲加載:一開始只初始化最須要的佈局,異步加載圖片,非當即須要的組件能夠作延遲加載。

別讓 Application 初始化沒必要要的東西

在 Application 初始化的地方作太多繁重的事情是可能致使嚴重啓動性能問題的元兇之一。Application 裏面的初始化操做不結束,其餘任意的程序操做都沒法進行。

有時候,咱們會一股腦的把絕大多數全局組件的初始化操做都放在 Application 的 onCreate() 裏面,但其實不少組件是須要作區隊對待的,有些能夠作延遲加載,有些能夠放到其餘的地方作初始化操做,特別須要留意包含 Disk IO 操做,網絡訪問等嚴重耗時的任務,他們會嚴重阻塞程序的啓動。


優化這些問題的解決方案是作延遲加載,能夠在 Application 裏面作延遲加載,也能夠把一些初始化的操做延遲到組件真正被調用到的時候再作加載。

恰當地使用閃屏

啓動閃屏不只僅能夠做爲品牌宣傳頁,還可以減輕用戶對啓動耗時的感知,可是若是使用不恰當,將拔苗助長。前面介紹過當點擊桌面圖標啓動 APP 的時候,程序會顯示一個啓動窗口,一直到頁面的渲染加載完畢。若是程序的啓動速度足夠快,咱們看的閃屏窗口停留顯示的時間則會很短,可是當程序啓動速度偏慢的時候,這個啓動閃屏能夠必定程度上減輕用戶等待的焦慮感,避免用戶過於輕易的關閉應用。

目前大多數開發者都會經過設置啓動窗口主題的方式來替換系統默認的啓動窗口,經過這種方式只是使用『障眼法』弱化了用戶對啓動時間的感知,但本質上並無對啓動速度作什麼優化。也有些 APP 經過關閉啓動窗口屬性 android:windowDisablePreview 的方式來直接移除系統默認的啓動窗口,可是這樣的弊端是用戶從點擊桌面圖標到真的看到實際頁面的這段時間當中,畫面沒有任何變化,這樣的用戶體驗是十分糟糕的!

對於啓動閃屏,正確的使用方法是自定義一張圖片,把這張圖片經過設置主題的方式顯示爲啓動閃屏,代碼執行到主頁面的 onCreate() 的時候設置爲程序正常的主題。

後記

本篇咱們根據胡凱老師總結,解決了啓動速度響應,下期咱們將帶來內存管理章節。
若是想第一時間收到更新信息的能夠關注個人簡書:簡書地址
你也能夠選擇關注個人公衆號:nanchen

相關文章
相關標籤/搜索