什么是ANR異常
ANR即Application Not Responding程序無響應(yīng)介牙,主要有以下三種情況會(huì)報(bào)ANR異常:
1壮虫、Activity的響應(yīng)時(shí)間超過5s;
2环础、BroadcastReceiver執(zhí)行時(shí)間超過10s囚似;
3剩拢、Service執(zhí)行時(shí)間超過20s;
造成ANR的原因
1谆构、在主線程中執(zhí)行了耗時(shí)操作裸扶,比如網(wǎng)絡(luò)讀取圖片數(shù)據(jù)并進(jìn)行圖片轉(zhuǎn)換框都;
2搬素、在主線程中進(jìn)行IO讀寫、磁盤讀寫魏保、數(shù)據(jù)庫讀寫等操作熬尺;
3、在主線程中大量創(chuàng)建新對象谓罗;
Android中執(zhí)行在主線程的操作
1粱哼、Activity的所有生命周期回調(diào)方法;
2檩咱、Service默認(rèn)是執(zhí)行在主線程的揭措;
3、BroadcastReceiver的onReceiver()回調(diào)方法刻蚯;
4绊含、沒有使用子線程的looper的Handler的handlerMessage()方法,post(Runnable r)方法;
5、AsyncTask除了doInBackground()方法之外其它的方法都是執(zhí)行在主線程中骏掀;
如何避免ARN
1噪舀、在UI線程中不要進(jìn)行耗時(shí)操作;比如在Activity的onCreate()或者onResume()生命周期中不要做耗時(shí)操作音羞;
2、創(chuàng)建子線程來執(zhí)行耗時(shí)操作;
3伴找、盡量使用Handler來處理主線程和子線程之間的交互;
4废菱、可以使用AsyncTask來執(zhí)行異步任務(wù)并及時(shí)更新UI技矮;
如何排查ANR
1、查看報(bào)錯(cuò)的Log日志文件昙啄;具體可查看ANR的類型穆役,CPU的使用情況等信息,并不能進(jìn)行準(zhǔn)確定位梳凛;
2耿币、分析traces.txt文件;如果發(fā)生ANR異常韧拒,系統(tǒng)會(huì)在/data/anr/目錄下生成traces.txt文件淹接,可以通過分析traces.txt文件來查看產(chǎn)生ANR的原因十性,但前提是手機(jī)需要Root獲取相應(yīng)的權(quán)限;
3塑悼、使用BlockCanary第三方監(jiān)控組件劲适,BlockCanary可以對主線程進(jìn)行完全透明的監(jiān)控,而且如果遇到UI卡頓時(shí)能精確輸出信息定位到問題所在厢蒜,不需要像Logcat一樣霞势,慢慢去找。
BlockCanary的工作原理:
主要利用了主線程中的消息處理機(jī)制斑鸦,在主線程中ActivityThread會(huì)默認(rèn)創(chuàng)建一個(gè)Looper愕贡,而Looper會(huì)調(diào)用loop()方法不斷從消息隊(duì)列MessageQueue取出消息,然后通過dispatchMessage()方法進(jìn)行消息的處理巷屿,通過ActivityThread的源碼可以發(fā)現(xiàn)在dispatchMessage()方法的前后都有l(wèi)og輸出事件固以,而dispatchMessage()是一次消息的處理過程,我們就可以計(jì)算從消息處理開始到消息處理結(jié)束的時(shí)間嘱巾,如果這個(gè)時(shí)間超過了16ms的話憨琳,那么就可以認(rèn)定是發(fā)生了UI卡頓現(xiàn)象,進(jìn)而輸出異常日志信息旬昭。
BlockCanary輸出的信息:
(1)基本信息:安裝包標(biāo)示篙螟、機(jī)型、api等級稳懒、uid闲擦、CPU內(nèi)核數(shù)、進(jìn)程名场梆、內(nèi)存墅冷、版本號等;
(2)耗時(shí)信息:實(shí)際耗時(shí)或油、主線程時(shí)鐘耗時(shí)寞忿、卡頓開始時(shí)間和結(jié)束時(shí)間;
(3)CPU信息:時(shí)間段內(nèi)CPU是否忙顶岸,時(shí)間段內(nèi)的系統(tǒng)CPU/應(yīng)用CPU占比腔彰,I/O占CPU使用率;
(4)堆棧信息:發(fā)生卡慢前的最近堆棧辖佣,可以用來幫助定位卡慢發(fā)生的地方和重現(xiàn)路徑霹抛;