ANR產生的原因
只有當應用程序的UI線程響應超時纔會引起ANR,超時產生原因一般有兩種。
1 當前的事件沒有機會得到處理,例如UI線程正在響應另外一個事件,當前事件由於某種原因被阻塞了。
2 當前的事件正在處理,但是由於耗時太長沒能及時完成。
根據ANR產生的原因不同,超時時間也不盡相同,從本質上講,產生ANR的原因有三種,大致可以對應到Android 中四大組件中的三個(Activity/View,BroadcastReceiver和Service)。
-
KeyDispatchTimeOut :最常見的一種類型,原因是View的按鍵事件或者觸摸事件在特定的時間(5秒)內無法得到響應。
-
BroadcaseTimeOut:原因是BroadcastReceiver的onReceiver()函數運行在主線程中,在特定的時間(10秒)內無法完成處理。
-
ServiceTimeOut:比較少出現的一種類型,原因是Service的各個生命週期函數在特定時間(20秒)內無法完成處理。
系統源碼中修改ANR的timeout時間
從上面可以知道,ANR產生的原因,以及android 系統對其的等待時間,如果想要修改這個時間,減小ANR發生的概率,可以在以下代碼中修改:
frameworks/base / services/core/java/com/android/server/am/ActivityManagerService.java
- 1.KeyDispatchTimeout
// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
- 2.BroadcastTimeOut
// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
- 3.ServiceTimeOut
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000;
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;