關於UI卡頓:
簡單的來說UI卡頓就是,微量級的anr。
複雜的來說:
原理:
60fps ->16ms
每秒60幀就能讓人看起來不卡頓,也就是說程序的操作必須在16ms內加載完畢。
導致卡頓的原因就是,程序頁面太過複雜,而在這16ms內沒有渲染完畢。
在Android中造成卡頓的原因:
Android系統每隔16ms會發出信號,就會觸發UI渲染,每次渲染成功就會讓UI流暢。(CPU,GPU這段時間內執行完所有操作)
- ListView或RecycleView 的itemlayout過於複雜
- 動畫同一時間執行的太多,導致cpu,gpu負載過重。
- 頻繁GC操作導致卡頓,Dalvik在每次GC時,會將所有的線程暫停,GC完後則纔開始。
- 人爲的在主線程中操作輕微的耗時操作。(耗時就是anr)
- 佈局layout過於複雜(background絕對不要重疊)
- view過度繪製
- View頻繁出發measure,layout,累計耗時過多及整個View頻繁的重新渲染。
- 冗餘資源以及邏輯導致加載和執行慢
overdraw(過度繪製)同一個像素繪製多次,各個像素有大量重疊的部分。
- 多層次的ui結構
系統調試:
開啓Android過度繪製調試
- 淺藍色代表屏幕上一個像素只被繪製了一次。
- 薄荷綠代表屏幕上一個像素被繪製了兩次。
- 淺粉色代表屏幕上一個像素被繪製了三次。
- 紅色代表屏幕上一個像素被繪製了四次及以上。
例子:主layout有background,子view也有background,就會進行過度繪製,減少重疊的部分繪製,就能降低UI卡頓
GPU呈現模式分析:
綠色爲基準線,意思是16ms,如果超過這個線就說明丟幀了。
如何優化:
1、使用merge標籤
使用merge來減少沒用的layout嵌套
2、ViewStub標籤
當系統碰到ViewStub標籤的時候是不進行任何處理(measure、layout等),比設置View隱藏、不可見更高效。當我們真正需要顯示某一個佈局的時候纔去渲染。
3、include標籤
重用代碼減少冗餘
4、儘量不要嵌套佈局
複雜佈局採用ConstraintLayout
5、儘量減少layout中不必要的背景設置,有圖片的話一定要壓縮
比如說根節點設置背景色,使得RecycleView中有間隔分割線。圖片過大會導致大量的內存消耗。
6、大面積的不可見區域儘量不要繪製,有需要的話建議動態繪製。
7、不要過於複雜的佈局
複雜佈局採用ConstraintLayout
8、用gone替代invisible
9、固定長和寬替代weight減少運算
layout_weight會使LinearLayout measure2次
10、item存在複雜的嵌套時可以採用自定義view來減少嵌套,減少measure測量和layout擺放的次數