四. Android 卡頓優(yōu)化

1. 工具選擇

CPU Profiler、Systrace、StrictMode

原因復(fù)雜:代碼、內(nèi)存、繪制、IO均有可能導(dǎo)致卡頓。難以定位。
不易復(fù)現(xiàn):當(dāng)時(shí)場(chǎng)景強(qiáng)相關(guān)。

CPU Profiler:圖形的形式展示執(zhí)行時(shí)間、調(diào)用棧等。信息全面,包含所有線程。整體會(huì)變慢。
使用方式:

Debug.startMethodTracing("");
Debug.stopMethodTracing("");

生成文件在SD卡:Android/data/packagename/files

Systrace:監(jiān)控和跟蹤Api調(diào)用、線程運(yùn)行情況,生成Html報(bào)告

API 18以上使用,推薦TraceCompat

python systrace.py -t 10 [other-options] [categories]

https://developer.android.com/studio/command-line/systrace#command_options

優(yōu)點(diǎn):輕量級(jí)、開銷小。直觀反映CPU利用率。給出建議(Alert)
StrictMode:嚴(yán)苛模式,Android提供的一種運(yùn)行時(shí)檢測(cè)機(jī)制。方便強(qiáng)大,容易被忽視。
包含:線程策略和虛擬機(jī)策略檢測(cè)。

線程策略:自定義的耗時(shí)調(diào)用,detectCustomSlowCalls()
磁盤讀取操作,detectDiskReads
網(wǎng)絡(luò)請(qǐng)求操作

虛擬機(jī)策略:
Activity泄漏,detectActivityLeaks()
Sqlite泄漏,detecteLeakedSqliteObjects
檢測(cè)實(shí)例數(shù)量,setClassInstanceLimit()

2. 自動(dòng)化卡頓檢測(cè)方案及優(yōu)化

原理:一個(gè)線程只有一個(gè)Looper
mLogging對(duì)象在每個(gè)message處理前后被調(diào)用
主線程發(fā)生卡頓,是在dispatchMessage執(zhí)行耗時(shí)操作

具體實(shí)現(xiàn):
1)Looper.getMainLooper().setMessageLogging();
2)匹配>>>>>Dispatching,閾值時(shí)間后執(zhí)行任務(wù)(獲取堆棧)
3)匹配<<<<<Finished,任務(wù)啟動(dòng)之前取消掉

AndroidPermormanceMonitor實(shí)戰(zhàn)(blockcanary)
非侵入性的性能監(jiān)控組件,通知形式彈出卡頓信息

問題及優(yōu)化
卡頓了,但卡頓堆棧可能不準(zhǔn)確。和OOM一樣,最后的堆棧只是表象,不是真正的問題。

優(yōu)化:獲取監(jiān)控周期內(nèi)的多個(gè)堆棧,而不僅是最后一個(gè)。
startMonitor -> 高頻采集堆棧-> endMonitor -> 記錄多個(gè)堆棧 -> 上報(bào)

海量卡頓堆棧處理
高頻卡頓上報(bào)量太大,服務(wù)端有壓力。
分析:一個(gè)卡頓下多個(gè)堆棧大概率有重復(fù)
解決:對(duì)一個(gè)卡頓下堆棧進(jìn)行hash排重,找出重復(fù)的堆棧。
效果:極大的減少展示量且找到真正發(fā)生問題的堆棧。

3. ANR分析與實(shí)戰(zhàn)

KeyDispatchTimeout:5s
BroadcastTimeout:前臺(tái)10s,后臺(tái)60s
ServiceTimeout:前臺(tái)20s,后臺(tái)200s

ANR執(zhí)行流程:發(fā)生ANR,進(jìn)程接收異常終止信號(hào),開始寫入進(jìn)程ANR信息。
彈出ANR提示框(ROM表現(xiàn)不一)

ANR解決套路:

adb pull data/anr/traces.txt

存儲(chǔ)路徑。 根據(jù)此路徑來判斷是否ANR
詳細(xì)分析:cpu/io

線上ANR監(jiān)控方案
通過FileObserver 監(jiān)控文件變化,高版本會(huì)有權(quán)限問題

ANR-WatchDog
非侵入式ANR監(jiān)控組件

com.github.anrwatchdog:anrwatchdog:1.3.0

https://github.com/SalomonBrys/ANR-WatchDog

原理:
start -> post消息改值(主線程+1操作) -> 線程sleep
檢測(cè)值是否被修改 ->判斷ANR發(fā)生(沒有被修改 message沒有到即發(fā)生)
彌補(bǔ)高版本沒有權(quán)限讀取Trace.txt 的問題。結(jié)合使用
和BlockCanary區(qū)別:
BlockCanary監(jiān)控Msg。適合監(jiān)控卡頓。
ANR-WatchDog:看最終結(jié)果。適合補(bǔ)充ANR監(jiān)控。

3. 卡頓單點(diǎn)問題檢測(cè)方案

自動(dòng)化卡頓檢測(cè)方案并不夠。很多操作的耗時(shí)并沒有達(dá)到卡頓閾值,感受同樣不佳但是不會(huì)拋出異常堆棧信息。

體系化解決方案務(wù)必盡早暴露問題。
單點(diǎn)問題:主線程IPC、DB IO、View繪制操作

IPC問題監(jiān)測(cè):
監(jiān)測(cè)指標(biāo):IPC調(diào)用類型
調(diào)用耗時(shí)、次數(shù)
調(diào)用堆棧、發(fā)生線程。

常規(guī)方案:
IPC前后加埋點(diǎn)。不夠優(yōu)雅,容易忘記。維護(hù)成本大。

adb命令:

adb shell am trace-ipc start // 監(jiān)控的開始
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
//結(jié)束,存放信息
adb pull /data/local/tmp/ipc-trace.txt // 導(dǎo)出

優(yōu)雅方案:
ARTHook 還是 AspectJ
ARTHook 可以Hook系統(tǒng)方法。ASpectJ針對(duì)非系統(tǒng)方法。

IPC場(chǎng)景:PackageManger得到應(yīng)用信息、get到設(shè)備的ID、AMS等等。
固定的調(diào)用方式,最后會(huì)調(diào)用到 “android.os.BinderProxy” transact方法

4. 如何實(shí)現(xiàn)界面秒開

首先通過Systrace(查看是否跑滿CPU),優(yōu)雅異步 + 優(yōu)雅延遲初始化。
異步Inflate、X2C、繪制優(yōu)化
提前獲取頁面數(shù)據(jù)

界面秒開率統(tǒng)計(jì):
onCreate 到 onWindowFocusChanged
特定接口適配Activity

Lancet:輕量級(jí) AOP框架
編譯速度快,支持增量編譯

API簡(jiǎn)單,沒有任何多余代碼插入 apk
@Proxy 通常用與對(duì)系統(tǒng)API調(diào)用的Hook
@Insert 常用于操作 App與library的類

界面秒開監(jiān)控維度
1)onCreate到onWindowFocusChanged 兩方法調(diào)用的時(shí)間間隔。
總體耗時(shí)。
2)生命周期的耗時(shí)。
3)生命周期間隔的耗時(shí)

5. 優(yōu)雅監(jiān)控耗時(shí)盲區(qū)

生命周期間隔
onResume到Feed展示的間隔
舉例:postMessage,很有可能在Feed之前執(zhí)行

TraceView
特別適合一段時(shí)間內(nèi)的盲區(qū)監(jiān)控
線程具體時(shí)間做了什么,一目了然。
TraceView適合現(xiàn)在,可以監(jiān)控系統(tǒng)Msg。
動(dòng)態(tài)替換適合線上,只有應(yīng)用自身的Msg

線上方案:
所有方法都是Msg,mLogging?沒有Msg具體堆棧
AOP切Handler方法?不清楚準(zhǔn)確執(zhí)行時(shí)間
使用統(tǒng)一的Handler:定制具體方法
定制gradle插件,編譯器動(dòng)態(tài)替換。

6. 卡頓優(yōu)化技巧總結(jié)初步

耗時(shí)操作:異步、延遲
布局優(yōu)化:異步Inflate、X2C、重繪解決
內(nèi)存:降低內(nèi)存占用,減少GC時(shí)間。

Log / TraceView的HeapTaskDesk

卡頓優(yōu)化工具建設(shè)
Systrace:看出CPU使用情況
TraceView:看出線程在特定時(shí)間做什么。相對(duì)開銷比較大。

StrictMode也是很強(qiáng)大的
自動(dòng)化監(jiān)控工具建設(shè)。

Android Performance monitor。ANR - WatchDog
高頻采集,找出重復(fù)率高的堆棧。

卡頓監(jiān)控工具
單點(diǎn)問題:AOP、Hook

盲區(qū)監(jiān)控:gradle 編譯器替換。監(jiān)控所有主線程msg執(zhí)行耗時(shí),以及調(diào)用堆棧 superHandler。

通過注解調(diào)整所有Handler的父類。

卡頓監(jiān)控指標(biāo):
卡頓率、ANR率、界面秒開時(shí)間

交互時(shí)間、生命周期時(shí)間
上報(bào)環(huán)境、場(chǎng)景信息!

7. 卡頓優(yōu)化模擬面試

1)你是怎么做卡頓優(yōu)化的?
體現(xiàn)出來不同階段的進(jìn)步,結(jié)構(gòu)化思維。
經(jīng)歷了一些階段,第一階段:系統(tǒng)工具定位、解決。
第二階段:自動(dòng)化卡頓方案及優(yōu)化。
第三階段:線上卡頓及線下監(jiān)測(cè)工具建設(shè)。

2)你是怎么自動(dòng)化的獲取卡頓信息的?

mLogging.println

不一定準(zhǔn)確。可以高頻采集,找出重復(fù)堆棧!

3)卡頓的一整套解決方案是怎么做的?
線下(盡量早)、線上(全面自動(dòng)化、異常感知靈敏度)工具相結(jié)合的方式
特定難點(diǎn)突破:?jiǎn)吸c(diǎn)問題、盲區(qū)監(jiān)控
SuperHandler

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,635評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,733評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,935評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,172評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評(píng)論 1 282
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,595評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,908評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容