乾貨分享——Android ANR 詳情解析|8月更文挑戰

經過本篇閱讀,您將學習到如下內容android

  • ANR 概述
  • ANR的類型
  • ANR 產生的緣由
  • 如何分析解決 ANR問題
  • ANR 問題分析解決建議
  • MTK 平臺 ANR問題分析

ANR(Application Not Responding )應用無響應的簡稱,是爲了在APP卡死時,用戶能夠強制退出APP的選擇,從而避免卡機無響應問題,這是android系統的一種自我保護機制。程序員

1、 ANR 概述

在Android中,應用程序響應由Activity Manager和Window Manager系統服務進行監視。ANR(Application Not Responding ),則是Android的一種自我保護措施,當主線程出現卡頓時候,Android 系統會給用戶一個彈出提示,讓用戶手動選擇繼續等待仍是強制關閉此APP。web

當Android檢測到如下狀況之一時,Android將顯示特定應用程序的ANR對話框,好比如下三種狀況下ANR將常常發生:面試

  • UI Thread超過 5 s沒有響應
  • Broadcast廣播超過10 s沒響應
  • Service 服務超過 20s 沒響應

所以,爲避免ANR發生,請不要在主線程中進行耗時操做,耗時操做請儘可能在子線程中運行。 4.發生ANR截圖 以下:markdown

2、 ANR的類型

ANR在Android 手機中很常見,按其相應類型能夠分爲如下 常見 三種類型。 ANR類型以下:網絡

按鍵響應分發超時(Key Dispatch Timeout) 默認 5 s,超過則會出現ANR。 廣播超時(Broadcast Timeout) 默認 10 s,超過則會出現ANR。 服務超時(Service Timeout) 默認 20 s,超過則會出現ANR。app

3、ANR 產生的緣由

在Android系統中,APP 一般運行在一個UI Thread或者叫MainThread裏。而且Android中只有一個MainThread 和Main Message Queue。MainThread主要用於UI的繪製、事件響應,監聽與接收事件處理等功能。Main Message Queue 主要存放用戶要處理消息的隊列,主線程MainThread從消息隊列Main Message Queue中取消息Message後,儘快分發下去,一旦某條消息分發超時,則ANR可能發生。學習

所以,當ANR 發生時,咱們要分析ANR產生的緣由,也就是查找消息處理不及時的緣由。例如能夠從如下幾個疑問點進行分析:spa

1.爲何 APP不能獲取CPU時間片? 2.APP 是不是等待一些沒能及時處理的事件完成? 3.消息處理流程是否是太複雜?線程

4、如何分析解決 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.Traceview Traceview獲取正在運行的應用程序的跟蹤信息,分析此traces.txt文件 能夠推測出主線程在忙於某些事情。 traces文件一般保存在/data/anr/traces.txt下,你能夠直接用adb cat 查看,或者 adb pull出來均可以。 建議使用此方法

5、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 進行處理。 好比下面例子:

不建議在onReceive 方法中進行耗時操做,超過10s 未處理,會引發ANR

建議使用IntentService ,避免ANR發生

您的廣播接收機可使用goAsync()來通知系統須要更多的時間來處理消息。 可是,您應該在PendingResult對象上調用finish()。 如下示例顯示如何調用finish()以讓系統回收廣播接收器並避免ANR:

6、MTK 平臺 ANR問題分析

前提,抓取一份ANR的MTK log。

1.event_log 搜索關鍵字am_anr或者anr,分析並查看ANR緣由

  1. main_log

搜索關鍵字Application Not Responding或者anr,分析並查看ANR緣由。

乾貨未完待續

公衆號:程序員喵大人(專一於Android各種學習筆記、面試題以及IT類資訊的分享。)

相關文章
相關標籤/搜索