如果 Android 應用程式的 UI 執行緒遭阻斷的時間過長,系統會傳送「應用程式無回應」(ANR) 錯誤。本頁面說明不同類型的 ANR,並提供每種類型的診斷方法和修正建議。本頁面列出的所有預設逾時期限長度,皆是以 Android 開放原始碼計畫和 Pixel 裝置為準,具體時間因原始設備製造商 (OEM) 而異。
請注意,如要判斷造成 ANR 的原因,建議您分辨系統問題和應用程式問題。
系統狀態不佳時,下列問題可能會導致 ANR:
- 系統伺服器發生暫時性問題,導致通常很快完成的繫結器呼叫速度變慢。
- 系統伺服器發生問題,且裝置負載偏高,導致應用程式執行緒未排程。
如果可以,建議使用 Perfetto 追蹤記錄,這有助分辨系統問題和應用程式問題:
- 在 Perfetto 的執行緒狀態記錄中,確認應用程式的主執行緒是否正在執行或可供執行,即可瞭解主執行緒是否已排程。
- 查看
system_server
執行緒,確認是否有鎖定爭用等問題。 - 針對速度緩慢的繫結器呼叫查看回覆執行緒 (如有),瞭解速度緩慢的原因。
輸入調度逾時
如果應用程式的主執行緒未及時回應輸入事件 (例如滑動或按鍵事件),就會發生輸入調度 ANR。由於發生輸入調度逾時的當下,應用程式是在前景運作,使用者幾乎一定會看到,因此請務必減少這類情形。
預設逾時期限:5 秒。
輸入調度 ANR 通常是主執行緒發生問題所致。如果主執行緒在等待取得鎖定時遭到阻斷,則容器執行緒可能也是導致 ANR 的原因。
如要避免輸入調度 ANR,請採用下列最佳做法:
- 切勿在主執行緒上執行會造成阻斷或耗時較長的作業。建議使用
StrictMode
擷取主執行緒上意外發生的活動。 - 盡量減少主執行緒和其他執行緒之間的鎖定爭用情形。
- 盡量減少主執行緒上的非 UI 工作,例如在處理廣播或執行服務時的工作。
常見原因
以下列出發生輸入調度 ANR 的一些常見原因和修正建議。
原因 | 狀況說明 | 修正建議 |
---|---|---|
繫結器呼叫速度緩慢 | 主執行緒發出耗時較長的同步繫結器呼叫。 | 將呼叫移出主執行緒,或嘗試改善呼叫 (如果您擁有 API)。 |
連續多次發出繫結器呼叫 | 主執行緒連續發出多次同步繫結器呼叫。 | 請勿在緊密迴圈中執行繫結器呼叫。 |
造成阻斷的 I/O | 主執行緒發出造成阻斷的 I/O 呼叫,例如資料庫或網路存取呼叫。 | 將所有會造成阻斷的 I/O 移出主執行緒。 |
鎖定爭用 | 主執行緒在等待取得鎖定時遭到阻斷。 | 減少主執行緒和其他執行緒之間的鎖定爭用情形。改善其他執行緒中緩慢的程式碼。 |
高成本影格 | 在單一影格中算繪過多內容,導致嚴重卡頓。 | 減少算繪影格的工作。請勿使用 n2 演算法。針對捲動或分頁等作業使用高效率的元件,例如 Jetpack Paging 程式庫。 |
遭其他元件阻斷 | 廣播接收器等其他元件正在執行,並阻斷主執行緒。 | 請盡可能將非 UI 工作移出主執行緒,並在其他執行緒中執行廣播接收器。 |
GPU 停止運作 | GPU 停止運作屬於系統或硬體問題,會導致算繪作業遭到阻斷,進而造成輸入調度 ANR。 | 遺憾的是,這類問題通常無法從應用程式修正。如果可以,請與硬體團隊聯絡來排解問題。 |
偵錯方式
如要開始偵錯,請前往 Google Play 管理中心或 Firebase Crashlytics,查看 ANR 叢集簽章。叢集通常包含可能導致 ANR 的上層影格。
以下流程圖說明如何判斷造成輸入調度逾時 ANR 的原因。
Play Vitals 可偵測一些常見的 ANR 原因並協助偵錯。舉例來說,如果 Vitals 偵測到由鎖定爭用情形造成的 ANR,就會在 ANR 的「深入分析」部分提供問題摘要和修正建議。
無聚焦視窗
雖然觸控等事件會根據命中測試直接傳送至相關視窗,但按鍵等事件需要目標。這種目標稱為「聚焦視窗」。每個畫面只有一個焦點視窗,通常是使用者目前正在互動的視窗。如果找不到聚焦視窗,輸入內容會引發「無聚焦視窗 ANR」。無聚焦視窗 ANR 屬於一種輸入調度 ANR。
預設逾時期限:5 秒。
常見原因
無聚焦視窗 ANR 通常是由下列其中一個問題造成:
- 應用程式執行過多工作,且速度太慢,因而無法繪製第一個影格。
- 無法聚焦主視窗。如果視窗含有
FLAG_NOT_FOCUSABLE
標記,使用者就無法傳送按鍵或按鈕事件給視窗。
Kotlin
override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); }
廣播接收器逾時
如果廣播接收器未及時處理廣播,就會發生廣播接收器 ANR。若是同步接收器或未呼叫 goAsync()
的接收器,逾時表示 onReceive()
未及時完成。對於非同步接收器或呼叫 goAsync()
的接收器,逾時表示未及時呼叫 PendingResult.finish()
。
廣播接收器 ANR 經常在下列執行緒中發生:
- 主執行緒 (如果問題是應用程式啟動速度緩慢)。
- 執行廣播接收器的執行緒 (如果問題是
onReceive()
程式碼緩慢)。 - 廣播背景工作執行緒 (如果問題是
goAsync()
廣播程式碼緩慢)。
如要避免廣播接收器 ANR,請採用下列最佳做法:
- 確保應用程式快速啟動,因為如果應用程式完成啟動並開始處理廣播,啟動時間就會計入 ANR 逾時期限。
- 如果使用
goAsync()
,請確保能快速呼叫PendingResult.finish()
。這種 ANR 逾時情況與同步廣播接收器相同。 - 如果使用
goAsync()
,請確保背景工作執行緒並未與其他長時間執行或造成阻斷的作業共用。 - 請考慮使用
registerReceiver()
,在非主執行緒中執行廣播接收器,避免阻斷正在主執行緒中執行的 UI 程式碼。
逾時期限
廣播接收器逾時期限取決於是否已設定前景意圖標記,以及平台版本為何。
意圖類型 | Android 13 以下版本 | Android 14 以上版本 |
---|---|---|
前景優先意圖 (已設定 |
10 秒 |
10 到 20 秒,具體取決於程序是否產生 CPU 飢餓現象 |
背景優先意圖 (未設定 |
60 秒 |
60 到 120 秒,具體取決於程序是否產生 CPU 飢餓現象 |
如要確認是否已設定 FLAG_RECEIVER_FOREGROUND
標記,請在 ANR 主體中尋找「flg=」,檢查是否存在 0x10000000
。如果已設定這個位元,就表示意圖已設定 FLAG_RECEIVER_FOREGROUND
,因此逾時期限較短。
廣播逾時期限較短 (10 至 20 秒) 的 ANR 示例:
Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }
廣播逾時期限較長 (60 到 120 秒) 的 ANR 示例:
Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }
廣播時間計算方式
廣播時間長度會從 system_server
調度至應用程式時開始計算,並在應用程式完成廣播處理程序時結束。如果應用程式程序尚未開始執行,則還需要在 ANR 逾時期限內執行冷啟動。因此,應用程式啟動速度緩慢可能導致廣播接收器 ANR。
下圖為廣播接收器 ANR 與特定應用程式程序對應的時間軸。
接收器完成廣播處理程序後,就會停止計入 ANR 逾時期限,確切時間取決於使用的是同步或非同步接收器。
- 如果是同步接收器,會在
onReceive()
傳回時停止計入期限。 - 如果是非同步接收器,則會在呼叫
PendingResult.finish()
時停止計入期限。
常見原因
以下列出發生廣播接收器 ANR 的一些常見原因和修正建議。
原因 | 適用對象 | 狀況說明 | 修正建議 |
---|---|---|---|
應用程式啟動速度緩慢 | 所有接收器 | 應用程式執行冷啟動的時間過長。 | 加快應用程式啟動速度。 |
onReceive() 未排程 | 所有接收器 | 廣播接收器執行緒忙著執行其他工作,無法啟動 onReceive() 方法。 | 請勿在接收器執行緒上執行耗時較長的工作,或者請將接收器移至專屬執行緒。 |
onReceive() 速度緩慢 | 所有接收器,但主要為同步接收器 | onReceive() 方法已啟動,但遭到阻斷或速度緩慢,因此無法及時完成。 | 加快接收器程式碼的速度。 |
非同步接收器工作未排程 | goAsync() 接收器 | onReceive() 方法嘗試在遭阻斷的背景工作執行緒集區中執行工作,因此工作從未啟動。 |
改善造成阻斷或緩慢的呼叫,或使用不同的執行緒,分別處理廣播工作站和其他長時間執行的工作。 |
工作站速度緩慢或遭到阻斷 | goAsync() 接收器 |
處理廣播時,背景工作執行緒集區中出現造成阻斷或速度緩慢作業,因此未及時呼叫 PendingResult.finish 。 | 加快 async 接收器程式碼的速度。 |
忘記呼叫 PendingResult.finish |
goAsync() 接收器 |
程式碼路徑中缺少對 finish() 的呼叫。 |
確保一律呼叫 finish() 。 |
偵錯方式
根據叢集簽章和 ANR 報告,您可以找出執行接收器的執行緒,以及執行速度緩慢或缺少的特定程式碼。
以下流程圖說明如何判斷造成廣播接收器 ANR 的原因。
找出接收器程式碼
Google Play 管理中心會在 ANR 簽章中顯示接收器類別和廣播意圖。請找出以下項目:
cmp=<receiver class>
act=<broadcast_intent>
以下是廣播接收器 ANR 簽章的範例:
com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }
找出執行 onReceive() 方法的執行緒
如果使用 Context.registerReceiver
指定自訂處理常式,那麼請找出執行此處理常式的執行緒。若是其他情況,則可知是主執行緒。
示例:非同步接收器工作未排程
本節舉例說明廣播接收器 ANR 的偵錯方式。
假設 ANR 簽章如下所示:
com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }
依簽章判斷,廣播意圖為 android.accounts.LOG_ACCOUNTS_CHANGED
,接收器類別則為 com.example.app.MyReceiver
。
透過接收器程式碼,可以判斷執行緒集區「BG Thread [0,1,2,3]」是處理廣播的主要工作。查看堆疊傾印後,可以發現全部四個背景 (BG) 執行緒都具有相同模式:都會執行 getDataSync
這個造成阻斷的呼叫。由於所有 BG 執行緒都在忙碌中,無法及時處理廣播,因此引發了 ANR。
BG Thread #0 (tid=26) Waiting
at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture:563)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture:68)
at com.example.app.getDataSync(<MyClass>:152)
...
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.android.libraries.concurrent.AndroidExecutorsModule.lambda$withStrictMode$5(AndroidExecutorsModule:451)
at com.google.android.libraries.concurrent.AndroidExecutorsModule$$ExternalSyntheticLambda8.run(AndroidExecutorsModule:1)
at java.lang.Thread.run(Thread.java:1012)
at com.google.android.libraries.concurrent.ManagedPriorityThread.run(ManagedPriorityThread:34)
There are several approaches to fix the issue:
- Find out why
getDataSync
is slow and optimize. - Don't run
getDataSync
on all four BG threads. - More generally, ensure that the BG thread pool isn't saturated with long-running operations.
- Use a dedicated thread pool for
goAsync
worker tasks. - Use an unbounded thread pool instead of the bounded BG thread pool
Example: slow app startup
A slow app startup can cause several types of ANRs, especially broadcast
receiver and execute service ANRs. The cause of an
ANR is likely slow app startup if you see ActivityThread.handleBindApplication
in the main thread stacks.
Execute service timeout
An execute service ANR happens when the app's main thread doesn't start a
service in time. Specifically, a service doesn't finish executing
onCreate()
and onStartCommand()
or onBind()
within the
timeout period.
Default timeout period: 20 seconds for foreground service; 200 seconds for
background service. The ANR timeout period includes the app cold start, if
necessary, and calls to onCreate(), onBind()
, or onStartCommand()
.
To avoid execute service ANRs, follow these general best practices:
- Make sure that app startup is fast, since it's counted in the ANR timeout if the app is started to run the service component.
- Make sure that the service's
onCreate()
,onStartCommand()
, andonBind()
methods are fast. - Avoid running any slow or blocking operations on the main thread from other components; these operations can prevent a service from starting quickly.
Common causes
The following table lists common causes of execute service ANRs and suggested fixes.
Cause | What | Suggested fix |
---|---|---|
Slow app startup | The app takes too long to perform a cold start. | Optimize slow app start. |
Slow onCreate(), onStartCommand (), or
onBind() |
The service component's onCreate(),
onStartCommand (), or onBind() method takes too long to
execute on the main thread. |
Optimize slow code. Move slow operations off the critical path where possible. |
Not scheduled (main thread blocked before onStart() ) |
The app's main thread is blocked by another component before the service can be started. | Move other component's work off the main thread. Optimize other component's blocking code. |
How to debug
From the cluster signature and ANR report in Google Play Console or Firebase Crashlytics, you can often determine the cause of the ANR based on what the main thread is doing.
The following flow chart describes how to debug an execute service ANR.
If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:
Find the service component class in the ANR signature. In Google Play Console, the service component class is shown in the ANR signature. In the following example ANR details, it's
com.example.app/MyService
.com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly Executing service com.example.app/com.example.app.MyService
Determine whether the slow or block operation is part of app startup, the service component, or elsewhere by checking for the following important function call(s) in the main threads.
Function call(s) in main thread stacks What it means android.app.ActivityThread.handleBindApplication
App was starting up, so the ANR was caused by slow app start. <ServiceClass>.onCreate()
[...]
android.app.ActivityThread.handleCreateService
Service was being created, so the ANR was likely caused by slow onCreate()
code.<ServiceClass>.onBind()
[...]
android.app.ActivityThread.handleBindService
Service was being bound, so the ANR was likely caused by slow onBind()
code.<ServiceClass>.onStartCommand()
[...]
android.app.ActivityThread.handleServiceArgs
Service was being started, so the ANR was likely caused by slow onStartCommand()
code.For example, if the
onStartCommand()
method in theMyService
class is slow, the main threads will look like this:at com.example.app.MyService.onStartCommand(FooService.java:25) at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4820) at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(unavailable:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:205) at android.os.Looper.loop(Looper.java:294) at android.app.ActivityThread.main(ActivityThread.java:8176) at java.lang.reflect.Method.invoke(Native method:0)
如果沒有任何重要的函式呼叫,則可能是其他原因:
- 服務正在執行或關閉,這表示太晚取得堆疊。在這種情況下,可以將 ANR 忽略為誤判結果。
- 正在執行其他應用程式元件,例如廣播接收器。在這種情況下,可能是此元件的主執行緒遭到阻斷,導致服務無法啟動。
如果發現重要的函式呼叫,且可判斷 ANR 大致的發生位置,請檢查其餘主執行緒堆疊,找出執行速度緩慢的作業並加以改善,或將這類作業移出重要路徑。
- 確保應用程式快速啟動,因為如果應用程式完成啟動並開始執行內容供應器,啟動時間就會計入 ANR 逾時期限。
- 確保內容供應器查詢可快速處理。
- 切勿執行大量並行的阻斷繫結器呼叫,這類呼叫會阻斷應用程式的所有繫結器執行緒。
- 堆疊傾印延遲。執行緒復原的時間,是在 ANR 觸發與堆疊傾印之間的短暫空檔。搭載 Android 13 的 Pixel 延遲時間約為 100 毫秒,但可超過 1 秒。搭載 Android 14 的 Pixel 延遲時間通常不到 10 毫秒。
- 執行緒歸因錯誤。建構 ANR 簽章的執行緒,實際上並非導致 ANR 的無回應執行緒。在這種情況下,請嘗試判斷 ANR 是否屬於下列其中一種類型:
- 系統層級問題。由於系統負載過高或系統伺服器發生問題,因此程序未排程。
- 處理堆疊的時間過長和逾時。
- 程序在系統取得堆疊前終止。
如要進一步瞭解服務,請參閱下列頁面:
內容供應器沒有回應
當遠端內容供應器回應查詢的時間超過逾時期限,並遭到終止時,就會發生內容供應器 ANR。
預設逾時期限:由內容供應器使用 ContentProviderClient.setDetectNotResponding
指定。ANR 逾時期限涵蓋遠端內容供應器查詢的總執行時間,因此在遠端應用程式尚未執行的情況下,也會涵蓋冷啟動的時間。
如要避免內容供應器 ANR,請採用下列最佳做法:
常見原因
下表列出內容供應器 ANR 的常見原因和修正建議。
原因 | 狀況說明 | 信號 | 修正建議 |
---|---|---|---|
內容供應器查詢速度緩慢 | 內容供應器執行時間過長或遭到阻斷。 | android.content.ContentProvider$Transport.query 框架位於繫結器執行緒中。 |
改善內容供應器查詢。找出繫結器執行緒遭到阻斷的原因。 |
應用程式啟動速度緩慢 | 內容供應器的應用程式啟動時間過長。 | ActivityThread.handleBindApplication 框架位於主執行緒中。 |
改善應用程式啟動程序。 |
繫結器執行緒耗盡 - 所有繫結器執行緒都在忙碌中 | 所有繫結器執行緒都忙於處理其他同步要求,因此無法執行內容供應器繫結器呼叫。 | 應用程式未啟動、所有繫結器執行緒都在忙碌中,內容供應器也未執行。 | 減少繫結器執行緒的負載,也就是降低同步傳出的繫結器呼叫數量,或是減少在傳入呼叫時處理的工作量。 |
偵錯方式
對內容供應器 ANR 偵錯時,如要使用 Google Play 管理中心或 Firebase Crashlytics 的叢集簽章和 ANR 報告,請查看主執行緒和繫結器執行緒正在執行的作業。
以下流程圖說明內容供應器 ANR 的偵錯方式。
因內容供應器查詢速度緩慢,導致繫結器執行緒遭到阻斷時,繫結器執行緒會如以下程式碼片段所示。在此情況下,內容供應器查詢開啟資料庫的同時,正在等待鎖定。
binder:11300_2 (tid=13) Blocked
Waiting for osm (0x01ab5df9) held by at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers:182)
at com.example.app.MyClass.blockingGetOpenDatabase(FooClass:171)
[...]
at com.example.app.MyContentProvider.query(MyContentProvider.java:915)
at android.content.ContentProvider$Transport.query(ContentProvider.java:292)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
at android.os.Binder.execTransactInternal(Binder.java:1339)
at android.os.Binder.execTransact(Binder.java:1275)
因應用程式啟動速度緩慢,導致主執行緒遭到阻斷時,主執行緒會如以下程式碼片段所示。在此情況下,應用程式啟動速度之所以緩慢,是因為 Dagger 初始化期間發生鎖定爭用情形。
main (tid=1) Blocked
[...]
at dagger.internal.DoubleCheck.get(DoubleCheck:51)
- locked 0x0e33cd2c (a qsn)at dagger.internal.SetFactory.get(SetFactory:126)
at com.myapp.Bar_Factory.get(Bar_Factory:38)
[...]
at com.example.app.MyApplication.onCreate(DocsApplication:203)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6991)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2235)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8170)
at java.lang.reflect.Method.invoke(Native method:0)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
工作回應速度緩慢
如果應用程式回應 JobService.onStartJob()
或 JobService.onStopJob()
的時間過長,或花費太長時間才透過 JobService.setNotification()
提供通知,就會發生工作回應速度緩慢 ANR。這表示應用程式的主執行緒遭到阻斷,無法執行其他作業。
如果是 JobService.onStartJob()
或 JobService.onStopJob()
發生問題,請檢查主執行緒上的情況。如果是 JobService.setNotification()
發生問題,務必盡快呼叫此方法。請勿在提供通知前執行大量工作。
神秘 ANR
有時候,我們並不清楚發生 ANR 的原因,或是叢集簽章和 ANR 報告中的資訊不足以用來偵錯。在這類情況下,仍可以採取幾個步驟,判斷是否能對 ANR 採取行動。
訊息佇列閒置中或 nativePollOnce
如果在堆疊中看到 android.os.MessageQueue.nativePollOnce
框架,通常表示疑似無回應的執行緒其實處於閒置狀態,且正在等待循環器訊息。在 Google Play 管理中心,這類 ANR 的詳細資料類似如下:
Native method - android.os.MessageQueue.nativePollOnce
Executing service com.example.app/com.example.app.MyService
舉例來說,如果主執行緒處於閒置狀態,則堆疊類似如下:
"main" tid=1 NativeMain threadIdle
#00 pc 0x00000000000d8b38 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
#01 pc 0x0000000000019d88 /system/lib64/libutils.so (android::Looper::pollInner(int)+184)
#02 pc 0x0000000000019c68 /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
#03 pc 0x000000000011409c /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
at android.os.MessageQueue.nativePollOnce (Native method)
at android.os.MessageQueue.next (MessageQueue.java:339) at android.os.Looper.loop (Looper.java:208)
at android.app.ActivityThread.main (ActivityThread.java:8192)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)
以下為疑似無回應的執行緒處於閒置狀態的可能原因:
無堆疊框架
部分 ANR 報表未涵蓋發生 ANR 的堆疊,也就是堆疊傾印在產生 ANR 報告時失敗。缺少堆疊框架的可能原因如下:
[...]
--- CriticalEventLog ---
capacity: 20
timestamp_ms: 1666030897753
window_ms: 300000
libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
----- Waiting Channels: pid 7068 at 2022-10-18 02:21:37.<US_SOCIAL_SECURITY_NUMBER>+0800 -----
[...]
如果 ANR 沒有堆疊框架,您無法根據叢集簽章或 ANR 報告採取行動。如要偵錯,請查看應用程式的其他叢集,因為如果問題夠大,問題本身通常會有叢集,而叢集中會有堆疊框架。另一種做法是查看 Perfetto 追蹤記錄。
已知問題
由於系統是以非同步方式監控 ANR,因此若是為了在 ANR 觸發前完成廣播處理作業,而在應用程式程序中保留計時器,這項機制可能會無法正常運作。