原文地址:/file/2020/09/16/20200916104601_12.jpg Not Responding )應用無響應的簡稱,是為了在 APP卡死時,使用者 可以強制退出APP的選擇,從而避免卡機無響應問題,這是Android系統的一種自我保護機制。
通過本篇閱讀,您將學習到以下內容
一、 ANR 概述一、ANR 概述 二、ANR的型別 三、ANR 產生的原因 四、如何分析解決 ANR問題 五、ANR 問題分析解決建議 六、MTK 平臺 ANR問題分析
在Android中,應用程式響應由Activity Manager和Window Manager系統服務進行監視。ANR(Application Not Responding ),則是Android的一種自我保護措施,當主執行緒出現卡頓時候,Android 系統會給使用者一個彈出提示,讓使用者手動選擇繼續等待還是強制關閉此APP。
當Android檢測到以下情況之一時,Android將顯示特定應用程式的ANR對話方塊,比如以下三種情況下ANR將經常發生:
1.UI Thread超過 5 s沒有響應2.Broadcast廣播超過10 s沒響應3.Service 服務超過 20s 沒響應因此,為避免ANR發生,請不要在主執行緒中進行耗時操作,耗時操作請儘量在子執行緒中執行。
二、 ANR的型別ANR在Android 手機中很常見,按其相應型別可以分為以下 常見 三種類型。
ANR型別如下:
按鍵響應分發超時(Key Dispatch Timeout) 預設 5 s,超過則會出現ANR。廣播超時(Broadcast Timeout) 預設 10 s,超過則會出現ANR。服務超時(Service Timeout) 預設 20 s,超過則會出現ANR。三、ANR 產生的原因在Android系統中,APP 通常執行在一個UI Thread或者叫MainThread裡。並且Android中只有一個MainThread 和Main Message Queue。MainThread主要用於UI的繪製、事件響應,監聽與接收事件處理等功能。Main Message Queue 主要存放使用者要處理訊息的佇列,主執行緒MainThread從訊息佇列Main Message Queue中取訊息Message後,儘快分發下去,一旦某條訊息分發超時,則ANR可能發生。
因此,當ANR 發生時,我們要分析ANR產生的原因,也就是查詢訊息處理不及時的原因。例如可以從以下幾個疑問點進行分析:
1.為什麼 APP不能獲取CPU時間片?2.APP 是否是等待一些沒能及時處理的事件完成?3.訊息處理流程是不是太複雜?四、如何分析解決 ANR問題在分析ANR時有一些常見的模式可供選擇:
APP正在主執行緒上進行緩慢的I/O操作。APP正在主執行緒中進行很複雜的計算操作主執行緒正在對另一個程序執行同步Binder程式呼叫,但另一個程序需要很長時間才能返回結果。主執行緒在等待另一個正在長時間執行塊操作的子執行緒時被阻塞。主執行緒因為另一個執行緒死鎖,無論是Bind呼叫還是主執行緒呼叫,都不能讓主執行緒等待很久,更不能在主執行緒中進行復雜的計算。知道產生ANR的原因,那麼如何避免ANR 問題呢?1.Strict mode使用StrictMode可以幫助您在開發應用程式時在主執行緒上發現意外的I / O操作。 您可以在application或activity使用StrictMode。
2.關閉 ANR Dialog 提示檢視方法ANR控制的方法: 設定---- 開發者選項---顯示所有ANR
注意 : 如沒有開發者選項,請進入設定---關於手機--- 多次連擊 版本號 即可開啟隱藏的開發者選項的item
3.TraceviewTraceview獲取正在執行的應用程式的跟蹤資訊,分析此traces.txt檔案 可以推測出主執行緒在忙於某些事情。
traces檔案通常儲存在/data/anr/traces.txt下,你可以直接用adb cat 檢視,或者 adb pull出來都可以。
建議使用此方法
五、ANR 問題分析解決建議分析檢視ANR原因,接著解決ANR問題。
1. 耗時操作請放在工作現場中進行,可以使用Handler、AsyncTask等。
2. IO 操作(比如:網路操作、儲存操作等)也是引起ANR的常見因素。強烈建議在工作執行緒中進行。
3. 程式鎖競爭某些情況,ANR產生的原因不是直接因為在主執行緒中產生的。 比如: 工作執行緒對某個資源等上鎖,恰好此時,主執行緒需要此資源,如等待超時,則此時ANR可能發生。
4. 死鎖當主執行緒因為請求一個其他執行緒正在持有的資源而進入等待狀態時,ANR可能會發生。
5. 廣播接收慢應用程式可以通過廣播接收器響應廣播訊息,例如啟用或禁用飛航模式或更改連線狀態。 當應用程式花費太長時間來處理廣播訊息時,理論上超過10s 未處理完成,ANR可能會發生。
6.廣播 ANR發生在下列情況下:onReceive() 方法長時間未執行完畢。儘量避免在onReceive() 中進行耗時操作。
廣播接收者呼叫goAsync()方法並且未能在PendingResult物件上呼叫finish()。如要處理的廣播內容較多,請使用IntentService 進行處理。
比如下面例子:
3.不建議在onReceive 方法中進行耗時操作,超過10s 未處理,會引起ANR
您的廣播接收機可以使用goAsync()來通知系統需要更多的時間來處理訊息。 但是,您應該在PendingResult物件上呼叫finish()。 以下示例顯示如何呼叫finish()以讓系統回收廣播接收器並避免ANR:
六、MTK 平臺 ANR問題分析前提,抓取一份ANR的MTK log。
1.event_log搜尋關鍵字 am_anr或者anr,分析並檢視ANR原因
2. main_log搜尋關鍵字Application Not Responding或者anr ,分析並檢視ANR原因。
更多Android免費學習資源地址:【GitHub】(含Android架構視訊+BAT面試專題PDF+學習筆記)
Android免費學習資源地址:/file/2020/09/16/20200916104602_13.jpg