android 渲染的幾個(gè)關(guān)鍵詞
surfaceflinger -> 刷新率
編舞者 -> 制圖速度 choreographer /?k??ri?ɑ?ɡr?f?r/
vsync 垂直同步信號(hào).
一秒60幀, 16.66ms通過vsync信號(hào)觸發(fā)一次刷新.
卡頓的主觀因素
- main looper里的event事件的處理有沒有耗時(shí)問題.
- 測(cè)量, 布局, draw當(dāng)中的代碼運(yùn)行速度慢. 因此不要在這三個(gè)方法中進(jìn)行大量運(yùn)算.
- 布局層疊深度不要過深. 過深的話就會(huì)有很多view需要執(zhí)行測(cè)量, 布局, draw當(dāng)中的代碼.
卡頓的客觀因素
- JVM GC STW (stop the world)會(huì)讓所有線程, 包括UI線程都會(huì)暫停.
- binder通信, 和其他進(jìn)程的調(diào)用被卡住了.
使用systrace定位問題
事故類型是什么.
1.1 UI繪制導(dǎo)致的問題 綠色偏多導(dǎo)致超時(shí)
1.2 事件處理導(dǎo)致的問題 綠色偏多導(dǎo)致超時(shí)
1.3 層級(jí)過多導(dǎo)致的繪制超時(shí)
1.4 GC導(dǎo)致的超時(shí) UI線程 紫色頻繁
1.5 IO導(dǎo)致的超時(shí) UI線程 橙色頻繁
1.6 binder通信導(dǎo)致的超時(shí) UI線程 灰色頻繁
systrace是定位不到代碼具體的位置的, 它是用來定位事故類型的.
systrace的使用. 啟動(dòng)后, 手動(dòng)操作, 然后結(jié)束.
systrace會(huì)把這期間的幀率變化, 線程狀態(tài)給記錄下來.
在frame這欄里, 間歇性的稍微紅幾幀的地方不用去看, 可能當(dāng)時(shí)jvm在gc, 這種情況是可以接受的, 偶爾性的掉6,7幀不影響用戶體驗(yàn).
要看frame這欄里, 那種連續(xù)紅和黃的位置, 這才是卡頓發(fā)生的時(shí)間段.
之后看UIThread這欄 中 choreographer#doFrame 這行的顏色, 不同顏色對(duì)應(yīng)著不同的事故類型.
卡頓代碼的定位
可以使用開源的BlockCanary定位, 實(shí)現(xiàn)思路是通過ActivityThread里有個(gè)logging對(duì)象來記錄msg的處理開始和結(jié)束時(shí)間. 并且ActivityThread對(duì)外提供了setLogging()的方法. 因此可以在外部創(chuàng)建出一個(gè)自己的logging對(duì)象set進(jìn)去. 時(shí)間超過閾值的時(shí)候, 在log和通知里提示給用戶.
但定位有時(shí)候不準(zhǔn), 也有些在一些機(jī)型上, 通知不彈出的問題, 需要進(jìn)行適配解決.
還可以使用hugo和我自己開發(fā)的插樁庫, 在相關(guān)的Activity和View的頭部加注解, 對(duì)耗時(shí)方法進(jìn)行排查.
--- done.