1. 程式人生 > >Android效能優化-----卡頓、crash

Android效能優化-----卡頓、crash

一、效能問題

主要總結為4個類別:
1、卡頓:使用時避免出現卡頓,響應速度快,減少使用者等待的時間,滿足使用者期望。
2、crash:減低 crash 率和 ANR 率,不要在使用者使用過程中崩潰和無響應。
3、耗電:節省流量和耗電,減少使用者使用成本,避免使用時導致手機發燙。
4、包大小
效能問題的主要原因,但歸根到底,不外乎記憶體使用、程式碼效率、合適的策略邏輯、程式碼質量、安裝包體積這一類問題。

二、卡頓分析

卡頓的場景有很多,主要有:UI 繪製、應用啟動、頁面跳轉、事件響應;根本原因可以分為兩大類:
1、介面繪製:主要原因是繪製的層級深、頁面複雜、重新整理不合理,該場景更多出現在 UI 和啟動後的初始介面以及跳轉到頁面的繪製上。
    1.1、

View的繪製中有三個核心步驟,通過Measure和Layout來確定當前需要繪製的View所在的大小和位置,通過繪製(Draw)到surface
    1.2、繪製任務太重,繪製一幀內容耗時太長;主執行緒太忙了,導致VSYNC訊號來時還沒有準備好資料導致丟幀。
    1.3、效能問題需要藉助相應的的除錯工具,比如檢視 Layout 層次的 Hierarchy ViewGPU Profile 工具Systrace UI 效能分析除錯GPU過度繪製、和靜態程式碼檢查工具 Lint等,這些工具對效能優化起到非常重要的作用。
2、資料處理
:該原因是資料處理量太大,一般分為三種情況,一是資料在處理 UI 執行緒,二是資料處理佔用 CPU 高,導致主執行緒拿不到時間片,三是記憶體增加導致 GC 頻繁,從而引起卡頓。

三、卡頓的解決

1、佈局優化,主要通過減少層級、減少測量和繪製時間、提高複用性三個方面入手。總結如下:
減少層級:合理使用ConstraintLayout、RelativeLayout和LinerLayout,合理使用Merge。
提高顯示速度:使用ViewStub,它是一個看不見的、不佔佈局位置、佔用資源非常小的檢視物件。
佈局複用:可以通過include、merge、標籤來提高複用。
儘可能少用wrap_content:wrap_content會增加布局measure時計算成本,在已知寬高為固定值時,不用wrap_content。

2,避免過度繪製
過度繪製是指在螢幕上的某個畫素在同一幀的時間內被繪製了多次。在多層次重疊的UI結構中,如果不可見的UI也在做繪製的操作,就會導致某些畫素區域被繪製了多次,從而浪費了多餘的CPU以及GPU資源。
移除XML中非必須的背景,移除Window預設的背景、按需顯示佔位背景圖片
適時使用Color.TRANSPARENT,因為透明色Color.TRANSPARENT是不會被渲染的,他是透明的。
自定義View優化。使用canvas.clipRect()來幫助系統識別那些可見的區域,只有在這個區域內才會被繪製。

3,啟動優化
啟動主要完成三件事:UI佈局、繪製和資料準備。因此啟動速度優化就是需要優化這三個過程:
UI佈局。應用一般都有閃屏頁,優化閃屏頁的UI佈局,可以通過Profile GPU Rendering檢測丟幀情況。
啟動載入邏輯優化。可以採用分佈載入、非同步載入、延期載入策略來提高應用啟動速度。
資料準備。資料初始化分析,載入資料可以考慮用執行緒初始化等策略。

先測量activity的啟動時間-------Activity的reportFullyDrawn()方法 
windowIsTranslucent設定成true,就可以讓程式在初始化的時候視窗是透明的,初始化結束後程序主介面才會顯示出來,從而也就完全看不到白屏介面了
android:Background設定為圖片或者背景顏色

4、Application優化
很多第三方元件(包括App應用本身)都在 Application 中進行初始化
必要的元件一定要在主執行緒中立即初始化(入口 Activity 可能立即會用到)
重要元件的載入一定要在主執行緒中初始化,但是可以延遲初始化。
其他元件Bugly,x5核心初始化,SP的讀寫,友盟等元件放到子執行緒中初始化。(子執行緒初始化不能影響到元件的使用)

5,合理的重新整理機制
資料的變化,需要重新整理頁面來展示新的資料,但頻繁重新整理會增加資源開銷,並且可能導致卡頓發生,
儘量減少重新整理次數。
儘量避免後臺有高的CPU執行緒執行。
縮小重新整理區域。

四、降低Crash率

1、armeabi相容armeabi-v7和armeabi-v8a以及新的arm體系結構的問題,在gradle裡進行配置支援
2、Java層面藉助於Android全域性的異常捕捉方式比如Thread.setDefaultUncaughtExceptionHandler()等來實現
   C/C++層面,則通過signal的捕捉來處理
3、程式碼靜態處理方式和工具
   程式碼掃描和程式碼靜態安全檢測工具可以使用Coverity或類似的工具
   通過GodEyes-android或類似的工具進行掃描來避免可能觸發的Crash問題
4、Crash問題分析總結反饋補充測試用例和測試場景,加強測試手段。
5、對於空指標問題,越界問題,類查詢問題,資源查詢問題,非法引數問題,資料傳輸超限問題,資源載入引起的超時問題,資料庫問題,Bundle載入問題等通過程式碼掃描工具以及靜態安全檢測工具並結合Code Review在編譯階段和程式碼提交階段就儘可能避免,同時通過增加測試用例包括邊界點測試進一步避免Crash問題。