応答しないスレッドを見つける
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
このドキュメントでは、ANR スタックダンプで応答しないスレッドを特定する方法について説明します。以下の表に示すとおり、応答しないスレッドは ANR の種類によって異なります。
ANR の種類 |
応答しないスレッド |
入力ディスパッチ |
メインスレッド |
フォーカスがあるウィンドウが入力ディスパッチにない |
メインスレッド。通常、この種の ANR はブロックされたスレッドでは発生しません。 |
ブロードキャスト レシーバ(同期) |
onReceive() を実行しているスレッド。
非メインスレッドのカスタム ハンドラが Context.registerReceiver を使用して指定されていない限り、メインスレッドです。 |
ブロードキャスト レシーバ(非同期) |
コードで、goAsync の呼び出し後にどのスレッドまたはスレッドプールがブロードキャストを処理する作業を行っているかを確認します。 |
実行中のサービスのタイムアウト |
メインスレッド |
フォアグラウンド サービスの開始 |
メインスレッド |
コンテンツ プロバイダの応答なし |
以下のいずれか:
- ANR の原因がコンテンツ プロバイダのクエリが遅いことにある場合は、バインダー スレッド。
- ANR の原因がアプリの長い起動にある場合は、メインスレッド。
|
onStartJob または onStopJob の応答がない |
メインスレッド |
別のスレッドまたはプロセスに根本原因があるために、スレッドが応答しないことがあります。スレッドが応答しなくなる可能性がある待機は以下のとおりです。
- 別のスレッドで保持されているロックの待機。
- 別のプロセスに対する遅いバインダー呼び出しの待機。
応答しないスレッドの一般的な原因
応答しないスレッドの一般的な原因は以下のとおりです。
バインダー呼び出しが遅い
ほとんどのバインダー呼び出しは高速ですが、ロングテールはかなり遅くなることがあります。これは、デバイスが読み込まれる場合や、ロックの競合、受信したバインダー呼び出しの多さ、Hardware Abstraction Layer(HAL)のタイムアウトなどにより、バインダー返信スレッドが遅い場合に発生する可能性が高くなります。
この問題は、可能な限り、同期のバインダー呼び出しをバックグラウンド スレッドに移動することで解決できます。メインスレッドで呼び出しを行う必要がある場合は、呼び出しが遅い理由を突き止めます。このためには、Perfetto トレースを使用することをおすすめします。
スタックで BinderProxy.transactNative
または Binderproxy.transact
を探します。
これは、バインダー呼び出しが行われていることを意味します。これらの 2 つの行の後で、呼び出されるバインダー 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)
[...]
コストのかかるフレーム
以下のように、1 つのフレーム内にレンダリングするものが多すぎると、そのフレームの最中にメインスレッドが応答しなくなることがあります。
- 数多くの不要な画面外アイテムをレンダリングする。
- 多くの UI 要素をレンダリングする際に、
O(n^2)
などの非効率的アルゴリズムを使用している。
他のコンポーネントによるブロック
ブロードキャスト レシーバなどの別のコンポーネントによってメインスレッドが 5 秒以上ブロックされると、入力ディスパッチの ANR や重大なジャンクが発生することがあります。
アプリ コンポーネントのメインスレッドで負荷の大きい処理を行わないでください。ブロードキャスト レシーバは、可能な限り別のスレッドで実行してください。
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-07-27 UTC。
[[["わかりやすい","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 UTC。"],[],[],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."]]