1.什么是ANR
在Android上,如果你的應(yīng)用程序有一段時間響應(yīng)不夠靈敏局装,系統(tǒng)會向用戶顯示一個對話框,這個對話框稱作應(yīng)用程序無響應(yīng)(ANR:Application Not Responding)對話框躁垛。用戶可以選擇讓程序繼續(xù)運行川梅,但是,他們在使用你的應(yīng)用程序時乔遮,并不希望每次都要處理這個對話框扮超。因此,在程序里對響應(yīng)性能的設(shè)計很重要蹋肮,這樣出刷,系統(tǒng)不會顯示ANR給用戶。
2.ANR產(chǎn)生的原因
ANR產(chǎn)生的根本原因是APP阻塞了UI線程括尸。在android系統(tǒng)中每個App只有一個UI線程巷蚪,是在App創(chuàng)建時默認生成的病毡,UI線程默認初始化了一個消息循環(huán)來處理UI消息濒翻,ANR往往就是處理UI消息超時了。那么UI消息來源有哪些呢啦膜?主要有兩種來源:
2.1 來自于AMS的回調(diào)消息
在Android系統(tǒng)中有送,應(yīng)用程序是有Android的四大組件組成,AMS負責(zé)對應(yīng)用程序四大組件生命周期的管理僧家,當AMS對應(yīng)用程序組件的生命周期進行回調(diào)超過AMS定義的響應(yīng)時間時雀摘,AMS就會報ANR。出現(xiàn)這種情況八拱,一般是因為在這些組件的回調(diào)函數(shù)里面進行了耗時操作(如網(wǎng)絡(luò)操作阵赠、SD卡文件操作、數(shù)據(jù)庫操作肌稻、大量計算等)清蚀,AMS對組件常見的回調(diào)函數(shù)及超時時間如下:
Activity: onCreate(), onResume(), onDestroy(),
onKeyDown(), onClick()等,超時時間5s
Application: onCreate(), onTerminate()等爹谭,超時時間5s
Service: onCreate(), onStart(), onDestroy()等枷邪,超時時間20s
BroadcastReceiver:onReceiver(),前臺APP廣播超時時間是10s诺凡,后臺App是60s
2.2 App自己的發(fā)出的消息
除了AMS對四大組件的回調(diào)消息運行在UI線程外东揣,有些操作也是運行在UI線程的:
AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel()等践惑,超時5s
Mainthread handler: handleMessage(), post*(runnable r)等,超時5s
3.怎樣避免ANR
當我們知道ANR的產(chǎn)生原因之后嘶卧,就可以較為輕松的避免ANR了尔觉。并且Android為我們提供了很多解決方法。主要歸為一下幾類脸候。
1:UI線程盡量只做跟UI相關(guān)的工作穷娱,但一些復(fù)雜的UI操作,還是需要一些技巧來處理运沦,不如你讓一個Button去setText一個10M的文本泵额,UI肯定崩掉了,不過對于此類問題携添,分段加載貌似是最好的方法了嫁盲。
2:讓耗時的工作(比如數(shù)據(jù)庫操作,I/O烈掠,連接網(wǎng)絡(luò)或者別的有可能阻礙UI線程的操作)把它放入單獨的線程處理羞秤。
3:盡量用Handler來處理UIthread和別的thread之間的交互。
4.發(fā)布的程序怎樣收集ANR異常
對于發(fā)布的程序左敌,ANR異常是很那捕獲不到的(我查找過很多資料瘾蛋,如果您有很好的捕獲辦法,歡迎再下方留言)矫限,所以我們需要采用其它的方法來分析ANR哺哼。app在產(chǎn)生ANR異常后,會將異常信息寫入"/data/anr/traces.txt"文件我們可以通過收集用戶的這個文件叼风,就可以來獲取用戶產(chǎn)生ANR的地方了取董。
我在一個按鈕的onClick事件里寫了如下代碼
while(true){}
來故意產(chǎn)生一個ANR異常,然后打開/data/anr/traces.tx文件无宿,主要有用的地方如下圖:
我們可以看到茵汰,在trace.txt文件里已經(jīng)定位到異常產(chǎn)生的地方。所以孽鸡,在用戶反饋界面蹂午,當我們發(fā)現(xiàn)戶反饋內(nèi)容里是否出現(xiàn)了"無響應(yīng)"等字眼的時候,就可以提示用戶是否上傳異常文件彬碱,來幫助我們改善產(chǎn)品之類的豆胸。當然,現(xiàn)在流氓猖狂堡妒,貌似做到這么細致產(chǎn)品的配乱,為數(shù)不多了。
ANR屬于慢性崩潰,Android應(yīng)用里的還存在著很多的強制崩潰搬泥,別如你執(zhí)行了3/0了桑寨,空指針異常了等等,這些情況應(yīng)用程序會直接崩掉忿檩,用戶體驗超級差尉尾,關(guān)于崩潰的相關(guān)內(nèi)容可以查看我的另一篇博文http://blog.saymagic.cn/2014/09/25/Android%E5%B4%A9%E6%BA%83%E5%AE%8C%E5%85%A8%E8%A7%A3%E6%9E%90.html。