參考列表:
https://blog.csdn.net/abm1993/article/details/80455032
https://blog.csdn.net/h1130189083/article/details/78147189
一、ANR 定義及分類
??????? ANR(Application Not Responding):應(yīng)用程序無響應(yīng),是 Android 中 AMS 與 WMS 監(jiān)控應(yīng)用相應(yīng)超時時的反應(yīng)。ANR 發(fā)生在 UI 線程轻庆,與四大組件對應(yīng)犹赖,在調(diào)用生命周期函數(shù)超時時發(fā)生袍患,分為以下四類:
1瓣蛀、KeyDispatchTimeout(5 秒)
按鍵或觸屏事件,5秒鐘之內(nèi)沒有得到執(zhí)行寇窑,當(dāng)設(shè)置中開啟ANR彈窗時,默認(rèn)情況下箩张,當(dāng)有事件派發(fā)時甩骏,才會觸發(fā)彈窗ANR。
ANR 日志中出現(xiàn)的關(guān)鍵字:Reason: Input dispatching timed out xxxx
2先慷、BroadcastTimeout(前臺廣播 10 秒饮笛;后臺廣播 60 秒)
BroadcastReceiver 在特定時間內(nèi),onReceiver() 方法沒有處理完成论熙,設(shè)置中開啟ANR彈窗時福青,默認(rèn)情況下,無彈窗赴肚,有l(wèi)og素跺。設(shè)置前臺廣播時需要加上FLAG_RECEIVER_FOREGROUND 標(biāo)識
ANR 日志中出現(xiàn)的關(guān)鍵字:Timeout executing service:/executing service XXX
3、ServiceTimeout(前臺服務(wù) 20 秒誉券;后臺服務(wù) 200 秒)
Service 在特定事件內(nèi)沒有處理完成指厌,設(shè)置中開啟ANR彈窗時,默認(rèn)情況下踊跟,無彈窗踩验,有l(wèi)og。
ANR 日志中出現(xiàn)的關(guān)鍵字:Timeout of broadcast XXX/Receiver during timeout:XXX/Broadcast of XXX
4商玫、ContentProviderTimeout(10 秒)
ContentProvider 的 publish 在 10 秒內(nèi)箕憾,沒有執(zhí)行完。
ANR 日志中出現(xiàn)的關(guān)鍵字:timeout publishing content providers
二拳昌、原因歸納
(1)其他進程占用CPU導(dǎo)致本進程得不到CUP時間片袭异,例如其他進程頻繁讀寫;
(2)耗時網(wǎng)絡(luò)請求炬藤;
(3)當(dāng)有大量數(shù)據(jù)正在讀寫操作時御铃,主線程再請求讀寫操作碴里,容易發(fā)生;
(4)數(shù)據(jù)庫操作(比如其他大數(shù)據(jù)量應(yīng)用訪問數(shù)據(jù)庫導(dǎo)致數(shù)據(jù)庫負(fù)載過重時)上真;
(5)硬件操作(Camera)咬腋;
(6)調(diào)用 Thread 的 join() 、sleep()睡互、wait() 方法根竿,或者等待線程鎖的時候;
(7)Service binder 的數(shù)量達到上限就珠;
(8)service 忙導(dǎo)致超時未響應(yīng)寇壳;
(9)在 system_server 中發(fā)生 WatchDog 的時候
(10)初始化的控件和數(shù)據(jù)過多
(11)內(nèi)存不足導(dǎo)致 block 在創(chuàng)建 bitmap 上
(12)其他線程有鎖,導(dǎo)致主線程等待超時嗓违;
(13)其他線程終止或者崩潰導(dǎo)致主線程超時九巡;
三、日志分析思路概要
1蹂季、在 log 日志中搜索關(guān)鍵字:am_anr冕广、InputDispatcher
(1)am_anr:通用的 ANR 第一時間點的 Log,Input 超時的時候可能會有延遲偿洁。
(2)InputDispatcher:當(dāng)有 input 超時的時候撒汉,該 Log? 打印時間點是 ANR 第一發(fā)生的時間點。
2涕滋、相關(guān)日志主要包含兩個:am_anr log睬辐、trace 文件
(1)am_anr 日志是由 (User|1|5)、(pid|1|5)宾肺、(Package Name|3)溯饵、(Flags|1|5)、(reason|3) 組成的锨用,我們根據(jù) reason 去分類 ANR 類型丰刊,然后根據(jù)不同的類型,以 am_anr 作為起始點往回看增拥,主要關(guān)注 timeout 時間內(nèi)啄巧,我們的應(yīng)用或者系統(tǒng)在做什么?
(2)trace 文件一般存在 data\anr 目錄掌栅,這里記錄了 ANR 發(fā)生時秩仆,應(yīng)用各個線程的調(diào)用堆棧信息,trace 文件也是分析 ANR 問題的關(guān)鍵猾封,但并不一定是絕對的準(zhǔn)確澄耍,trace 文件只是收集 ANR 發(fā)生時某一刻的調(diào)用堆棧信息。某一時刻請自行體會,多看一點ANR問題齐莲,便能體會卿城。(此處我也在體會中.......)
四、避免 ANR
(1)避免主線程執(zhí)行耗時操作铅搓。請注意 Handler ,是否使用的是主線程下的(異步處理操作搀捷,操作仍在 UI 主線程星掰,因為使用的是主線程的 Loop 和 Messagequeue),非主線程請使用 HandlerThread 嫩舟;
(2)BoardcastReceiver 要執(zhí)行耗時操作時應(yīng)啟動一個 Service,將耗時操作交給 Service 完成。
(3)避免在IntentReceiver里啟動一個Activity鄙皇,因為它會創(chuàng)建一個新的畫面褐奥,并從用戶當(dāng)前運行的程序上搶奪焦點。如果應(yīng)用需要在收到廣播時打開 Activity饭于,應(yīng)該使用 Notification Manager 實現(xiàn)蜀踏。