ANR

yzpyzp發表於2021-01-02

ANR概念

ANR(Application Not Responding) 應用程式無響應。如果應用程式在UI執行緒被阻塞太長時間,就會出現ANR,通常出現ANR,系統會彈出一個提示提示框,讓使用者知道,該程式正在被阻塞,是否繼續等待還是關閉。

出現ANR必須解決

ANR型別

KeyDispatchTimeout(常見)

input事件在5S內沒有處理完成發生了ANR。
logcat日誌關鍵字:Input event dispatching timed out

BroadcastTimeout

前臺Broadcast:onReceiver在10S內沒有處理完成發生ANR。
後臺Broadcast:onReceiver在60s內沒有處理完成發生ANR。
logcat日誌關鍵字:Timeout of broadcast BroadcastRecord

ServiceTimeout

前臺Service:onCreate,onStart,onBind等生命週期在20s內沒有處理完成發生ANR。
後臺Service:onCreate,onStart,onBind等生命週期在200s內沒有處理完成發生ANR
logcat日誌關鍵字:Timeout executing service

ContentProviderTimeout

ContentProvider 在10S內沒有處理完成發生ANR。
logcat日誌關鍵字:timeout publishing content providers

為什麼出現ANR

1:主執行緒頻繁進行耗時的IO操作:如資料庫讀寫
2:多執行緒操作的死鎖,主執行緒被block;held by
3:主執行緒被Binder 對端block;
4:System Server中WatchDog出現ANR;
5:service binder的連線達到上線無法和和System Server通訊
6:系統資源已耗盡(管道、CPU、IO)

ANR問題如何解決

traces_*.txt
*一般是firstPid,即發生anr的pid
ActivityManagerservice 中實現 通過appNotResponding(), dumpStackTraces() 兩個主要方法來生成應用的anr
traces_SystemServer_WDT.txt(watchdog)
Watchdog中實現
system_server程式棧資訊
traces.txt(dalvik.vm.stack-trace-file)
系統定義的預設trace檔案路徑

分析技巧

通過logcat日誌,traces檔案確認anr發生時間點
traces檔案和CPU使用率
/data/anr/traces.txt
主執行緒狀態
其他執行緒狀態

關鍵資訊

ANR時間:07-20 15:36:36.472
程式pid:1480
程式名:com.xxxx.moblie
ANR型別:KeyDispatchTimeout

main:main標識是主執行緒,如果是執行緒,那麼命名成“Thread-X”的格式,x表示執行緒id,逐步遞增。
prio:執行緒優先順序,預設是5
tid:tid不是執行緒的id,是執行緒唯一標識ID
group:是執行緒組名稱
sCount:該執行緒被掛起的次數
dsCount:是執行緒被偵錯程式掛起的次數
obj:物件地址
self:該執行緒Native的地址
sysTid:是執行緒號(主執行緒的執行緒號和程式號相同)
nice:是執行緒的排程優先順序
sched:分別標誌了執行緒的排程策略和優先順序
cgrp:排程歸屬組
handle:執行緒處理函式的地址。
state:是排程狀態
schedstat:從 /proc/[pid]/task/[tid]/schedstat讀出,三個值分別表示執行緒在cpu上執行的時間、執行緒的等待時間和執行緒執行的時間片長度,不支援這項資訊的三個值都是0;
utm:是執行緒使用者態下使用的時間值(單位是jiffies)
stm:是核心態下的排程時間值
core:是最後執行這個執行緒的cpu核的序號

執行緒狀態

THREAD_UNDEFINED = -1
THREAD_ZOMBIE = 0, /* TERMINATED /
THREAD_RUNNING = 1, /
RUNNABLE or running now /
THREAD_TIMED_WAIT = 2,/
TIMED_WAITING Object.wait()
THREAD_MONITOR = 3, /* BLOCKED on a monitor /
THREAD_WAIT = 4, /
WAITING in Object.wait() /
THREAD_INITIALIZING= 5, /
allocated, not yet running /
THREAD_STARTING = 6, /
started, not yet on thread list /
THREAD_NATIVE = 7, /
off in a JNI native method /
THREAD_VMWAIT = 8, /
waiting on a VM resource /
THREAD_SUSPENDED = 9, /
suspended, usually by GC or debugger

Android執行緒狀態

在這裡插入圖片描述

ANR監控方案1-watchdog

在這裡插入圖片描述
在這裡插入圖片描述

ANR監控方案2-FileObserver

Android系統在此基礎上封裝了一個FileObserver類來方便使用Inotify機制。FileObserver是一個抽象類,需要定義子類實現該類的onEvent抽象方法,當被監控的檔案或者目錄發生變更事件時,將回撥FileObserver的onEvent()函式來處理檔案或目錄的變更事件