找出無回應的會話串
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
本文件說明如何在 ANR 堆疊傾印中找出無回應的執行緒。無回應的執行緒會因 ANR 類型而異,如下表所示。
ANR 類型 |
無回應的執行緒 |
輸入調度 |
主執行緒 |
輸入調度無聚焦視窗 |
主執行緒。這類 ANR 通常不是因執行緒遭阻斷而造成。 |
廣播接收器 (同步) |
執行 onReceive() 的執行緒。除非使用 Context.registerReceiver 指定非主執行緒上的自訂處理常式,否則這會是主執行緒。 |
廣播接收器 (非同步) |
請查看程式碼,瞭解在呼叫 goAsync 後,是由哪個執行緒或執行緒集區負責處理廣播。 |
執行服務逾時 |
主執行緒 |
前景服務啟動 |
主執行緒 |
內容供應器沒有回應 |
以下兩者之一:
- 如果 ANR 發生原因是內容供應器查詢速度緩慢,則為繫結器執行緒。
- 如果 ANR 發生原因是應用程式啟動時間過長,則為主執行緒。
|
對 onStartJob 或 onStopJob 無回應 |
主執行緒 |
有時候,執行緒無回應是因為其他執行緒/程序中的根本問題。執行緒可能因等待以下項目而沒有回應:
- 由其他執行緒保留的鎖定。
- 對不同程序發出的緩慢繫結器呼叫。
導致執行緒無回應的常見原因
以下是導致執行緒無回應的常見原因。
繫結器呼叫速度緩慢
雖然大多數繫結器呼叫的速度都很快,但長尾呼叫可能非常慢。如果在載入裝置或繫結器回覆執行緒過慢時,例如因鎖定爭用、傳入許多繫結器呼叫,或硬體抽象層 (HAL) 逾時,就較可能出現這種情況。
如要解決這個問題,請盡可能將同步繫結器呼叫移至背景執行緒。如果呼叫必須在主執行緒上執行,請找出呼叫速度緩慢的原因。最佳做法是使用 Perfetto 追蹤記錄。
建議您在堆疊中尋找 BinderProxy.transactNative
或 Binderproxy.transact
,這表示繫結器呼叫正在執行。您可以依據這兩行程式碼,瞭解系統呼叫的繫結器 API 為何。在以下範例中,系統呼叫的是 IAccessibilityManager.addClient
。
main tid=123
...
android.os.BinderProxy.transactNative (Native method)
android.os.BinderProxy.transact (BinderProxy.java:568)
android.view.accessibility.IAccessibilityManager$Stub$Proxy.addClient (IAccessibilityManager.java:599)
...
連續多次發出繫結器呼叫
在緊密迴圈中連續多次執行繫結器呼叫,可能會長時間阻斷執行緒。
阻斷式 I/O
請勿在主執行緒上執行阻斷式 I/O,這屬於反模式。
鎖定爭用
如果執行緒在獲取鎖定時遭到阻斷,可能會導致 ANR。
以下是主執行緒在嘗試獲取鎖定時遭阻斷的例子:
main (tid=1) Blocked
Waiting for com.example.android.apps.foo.BarCache (0x07d657b7) held by
ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD
[...]
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5412)
[...]
阻斷式執行緒正在提出 HTTP 要求來下載影片:
ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD (tid=110) Waiting
at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:715)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1047)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:230)
at com.example.android.apps.foo.HttpRequest.execute(HttpRequest:136)
at com.example.android.apps.foo$Task$VideoLoadTask.downloadVideoToFile(RequestExecutor:711)
[...]
高成本影格
如果在單一影格中轉譯過多內容,可能會導致主執行緒在影格持續期間沒有回應,例如:
- 轉譯許多不必要的畫面外項目。
- 在轉譯許多 UI 元素時使用效率不佳的演算法,例如
O(n^2)
。
遭其他元件阻斷
如果廣播接收器等其他元件阻斷主執行緒的時間超過五秒,就可能導致輸入調度 ANR 和嚴重卡頓。
請避免在應用程式元件的主執行緒上執行大量作業,應盡可能在不同執行緒中執行廣播接收器。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Find the unresponsive thread\n\nThis document shows how to identify the unresponsive thread in an ANR stack\ndump. The unresponsive thread varies by type of ANR, as shown in the following\ntable.\n\n| ANR type | Unresponsive thread |\n|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Input dispatch | Main thread |\n| Input dispatch no focused window | Main thread. This type of ANR isn't usually caused by a blocked thread. |\n| Broadcast receiver (synchronous) | Thread running [onReceive()](/reference/android/content/BroadcastReceiver#onReceive(android.content.Context,%20android.content.Intent)). This is the main thread unless a custom handler on a non-main thread is specified using [Context.registerReceiver](/reference/android/content/Context#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter,%20java.lang.String,%20android.os.Handler,%20int)). |\n| Broadcast receiver (asynchronous) | Check the code to see which thread or thread pool is responsible for doing the work to process the broadcast after [goAsync](https://developer.android.com/reference/android/content/BroadcastReceiver#goAsync()) is called. |\n| Executing service timeout | Main thread |\n| Foreground service start | Main thread |\n| Content provider not responding | Either: - Binder thread if ANR is caused by a slow content provider query. - Main thread if ANR is caused by a long app startup. |\n| No response to [onStartJob](/reference/android/app/job/JobService#onStartJob(android.app.job.JobParameters)) or [onStopJob](/reference/android/app/job/JobService#onStopJob(android.app.job.JobParameters)) | Main thread |\n\nSometimes the thread is unresponsive due to a root cause in a different thread\nor process. The thread can be unresponsive due to waiting on the following:\n\n- A lock held by a different thread.\n- A slow binder call to a different process.\n\nCommon causes of unresponsive threads\n-------------------------------------\n\nThe following are common causes of unresponsive threads.\n\n### Slow binder call\n\nAlthough most binder calls are quick, the long tail can be very slow. This is\nmore likely to happen if the device is loaded or the binder reply thread is\nslow, such as from lock contention, many incoming binder calls, or [hardware\nabstraction layer (HAL)](/guide/platform#hal) timeout.\n\nYou can solve this by moving synchronous binder calls to background threads\nwherever possible. If the call must happen on the main thread, find out why the\ncall is slow. The best way to do this is from Perfetto traces.\n\nLook for `BinderProxy.transactNative` or `Binderproxy.transact` in the stacks.\nThis means a binder call is taking place. Following these two lines, you can see\nthe binder API that is called. In the following example, the call is to\n`IAccessibilityManager.addClient`. \n\n main tid=123\n\n ...\n android.os.BinderProxy.transactNative (Native method)\n android.os.BinderProxy.transact (BinderProxy.java:568)\n android.view.accessibility.IAccessibilityManager$Stub$Proxy.addClient (IAccessibilityManager.java:599)\n ...\n\n### Many consecutive binder calls\n\nPerforming many consecutive binder calls in a tight loop can block a thread for\na long period.\n\n### A blocking I/O\n\nNever perform blocking I/O on the main thread. This is an antipattern.\n\n### Lock contention\n\nIf a thread is blocked when acquiring a lock, it can result in an ANR.\n\nThe following example shows the main thread is blocked when trying to acquire a\nlock: \n\n main (tid=1) Blocked\n\n Waiting for com.example.android.apps.foo.BarCache (0x07d657b7) held by\n ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD\n [...]\n at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5412)\n [...]\n\nThe blocking thread is making a HTTP request to download a video: \n\n ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD (tid=110) Waiting\n\n at jdk.internal.misc.Unsafe.park(Native method:0)\n at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)\n at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:715)\n at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1047)\n at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:230)\n at com.example.android.apps.foo.HttpRequest.execute(HttpRequest:136)\n at com.example.android.apps.foo$Task$VideoLoadTask.downloadVideoToFile(RequestExecutor:711)\n [...]\n\n### Expensive frame\n\nRendering too many things in a single frame can cause the main thread to be\nunresponsive for the duration of the frame, such as the following:\n\n- Rendering many unnecessary off-screen items.\n- Using an inefficient algorithm, such as `O(n^2)`, when rendering many UI elements.\n\n### Blocked by other component\n\nIf another component, such as a broadcast receiver, blocks the main thread for\nmore than five seconds, it can cause input dispatch ANRs and serious jank.\n\nAvoid doing any heavy work on the main thread in app components. Run broadcast\nreceivers on a different thread wherever possible."]]