1. 程式人生 > >android ANR產生情況、發生原因及解決辦法

android ANR產生情況、發生原因及解決辦法

ANR (Application Not Responding)  

ANR定義:在Android上,如果你的應用程式有一段時間響應不夠靈敏,系統會向用戶顯示一個對話方塊,這個對話方塊稱作應用程式無響應(ANR:Application Not Responding)對話方塊。使用者可以選擇“等待”而讓程式繼續執行,也可以選擇“強制關閉”。所以一個流暢的合理的應用程式中不能出現anr,而讓使用者每次都要處理這個對話方塊。因此,在程式裡對響應效能的設計很重要,這樣系統不會顯示ANR給使用者。
預設情況下,在android中Activity的最長執行時間是5秒,BroadcastReceiver的最長執行時間則是10秒。

ANR產生情況

在Android裡,應用程式的響應性是由Activity Manager和WindowManager系統服務監視的 。當它監測到以下情況中的一個時,Android就會針對特定的應用程式顯示ANR:

1.在5秒內沒有響應輸入的事件(例如,按鍵按下,螢幕觸控)
2.BroadcastReceiver在10秒內沒有執行完畢

發生ANR的根本原因

  • 應用程序自身引起的:

    • .呼叫thread的join()方法、sleep()方法、wait()方法或者其他執行緒持有鎖或者其它執行緒終止或崩潰導致主執行緒等待超時;
    • service binder的數量達到上限,system server中發生WatchDog ANR,service忙導致超時無響應
    • 在主執行緒中做了非常耗時的操作:像耗時的網路訪問,大量的資料讀寫,資料庫操作,硬體操作(比如camera),耗時的計算如操作點陣圖;
  • 其他程序引起的,比如:其他程序CPU佔用率過高,導致當前應用程序無法搶佔到CPU時間片。常見的問題如檔案讀寫頻繁,io程序CPU佔用率過高,導致當前應用出現ANR;

ANR解決辦法

雖然每個程式設計師都不想ANR發生在自己的頭上,因此,你需要嚴格遵守Google提供的一系列建議,簡單總結就是以下兩點:

  • 不要讓主執行緒乾耗時的工作
    • Activity應該在它的關鍵生命週期方法(如onCreate()和onResume())裡儘可能少的去做建立操作。(可以採用重新開啟子執行緒的方式,然後使用Handler+Message非同步更新ui,還採用asyntask非同步任務的方式) ;
    • 避免在BroadcastReceiver裡做耗時的操作或計算。也不要開 子執行緒裡做這些任務(因為 BroadcastReceiver的生命週期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程式應該啟動一個 Service。
    • 避免在Broadcast Receiver裡啟動一個Activity,因為它會建立一個新的畫面,並從當前使用者正在執行的程式上搶奪焦點。如果你的應用程式在響應Intent廣播時需要向用戶展示什麼,你應該使用Notification Manager來實現
  • 不要讓其他執行緒阻塞主執行緒的執行

因此,要儘量保證主執行緒執行工作乾淨利落,一個訊息迴圈執行時間最好不超過100ms到200ms。一般應用程式在釋出之前最好對新增的功能通過Systrace+TraceView進行效能測試,這樣能夠及時發現程式當中的耗時操作,對於一些可能引起ANR的風險做到提前規避。