Android - ANR を調査するにはどうすればよいですか? 質問する

Android - ANR を調査するにはどうすればよいですか? 質問する

アプリが ANR (アプリケーションが応答しない) をスローした場所を見つける方法はありますか。/data の traces.txt ファイルを確認したところ、アプリケーションのトレースが見つかりました。トレースに表示される内容は次のとおりです。

DALVIK THREADS:
"main" prio=5 tid=3 TIMED_WAIT
  | group="main" sCount=1 dsCount=0 s=0 obj=0x400143a8
  | sysTid=691 nice=0 sched=0/0 handle=-1091117924
  at java.lang.Object.wait(Native Method)
  - waiting on <0x1cd570> (a android.os.MessageQueue)
  at java.lang.Object.wait(Object.java:195)
  at android.os.MessageQueue.next(MessageQueue.java:144)
  at android.os.Looper.loop(Looper.java:110)
  at android.app.ActivityThread.main(ActivityThread.java:3742)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:515)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #3" prio=5 tid=15 NATIVE
  | group="main" sCount=1 dsCount=0 s=0 obj=0x434e7758
  | sysTid=734 nice=0 sched=0/0 handle=1733632
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #2" prio=5 tid=13 NATIVE
  | group="main" sCount=1 dsCount=0 s=0 obj=0x433af808
  | sysTid=696 nice=0 sched=0/0 handle=1369840
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=11 NATIVE
  | group="main" sCount=1 dsCount=0 s=0 obj=0x433aca10
  | sysTid=695 nice=0 sched=0/0 handle=1367448
  at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=9 VMWAIT
  | group="system" sCount=1 dsCount=0 s=0 obj=0x433ac2a0
  | sysTid=694 nice=0 sched=0/0 handle=1367136
  at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
  | group="system" sCount=0 dsCount=0 s=0 obj=0x433ac1e8
  | sysTid=693 nice=0 sched=0/0 handle=1366712
  at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=5 VMWAIT
  | group="system" sCount=1 dsCount=0 s=0 obj=0x4253ef88
  | sysTid=692 nice=0 sched=0/0 handle=1366472
  at dalvik.system.NativeStart.run(Native Method)

----- end 691 -----

問題がどこにあるのかをどうやって調べればよいですか? トレース内のメソッドはすべて SDK メソッドです。

ベストアンサー1

ANR は、「メイン」スレッドで長時間の操作が行われると発生します。これはイベント ループ スレッドであり、ビジー状態の場合、Android はアプリケーションでそれ以上の GUI イベントを処理できず、ANR ダイアログが表示されます。

さて、あなたが投稿したトレースでは、メイン スレッドは正常に動作しているようで、問題はありません。メイン スレッドは MessageQueue でアイドル状態になっており、別のメッセージが到着するのを待っています。あなたの場合、ANR はスレッドを永続的にブロックするものではなく、より長い操作だった可能性が高いため、操作の終了後にイベント スレッドが回復し、トレースは ANR 後に通過しました。

ANR の発生場所の検出は、永続的なブロック (たとえば、ロックを取得するデッドロック) の場合は簡単ですが、一時的な遅延の場合は難しくなります。まず、コードを調べて、脆弱な箇所と長時間実行される操作を探します。例としては、ソケット、ロック、スレッド スリープ、イベント スレッド内からのその他のブロック操作の使用などがあります。これらがすべて別のスレッドで発生するようにしてください。問題がない場合は、DDMS (Dalvik Debug Monitor Service) を使用してスレッド ビューを有効にします。これにより、トレースに似たアプリケーション内のすべてのスレッドが表示されます。ANR を再現し、同時にメイン スレッドを更新します。これにより、ANR 発生時に何が起こっていたかが正確にわかるはずです。

おすすめ記事