1. ホーム
  2. android

[解決済み] Android - ANRを調査するにはどうしたらいいですか?

2022-04-24 17:31:29

質問

私のアプリがANR (Application Not Responding)を投げた場所を見つける方法はありますか?/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のメソッドです。

解決方法を教えてください。

ANRは、"main"スレッドで何か長い操作が行われたときに発生します。このスレッドはイベントループのスレッドで、これがビジー状態だとAndroidはアプリケーションのGUIイベントをそれ以上処理できないので、ANRダイアログが表示されます。

さて、投稿されたトレースでは、メインスレッドは問題なく動作しているようです。MessageQueueでアイドル状態になっており、別のメッセージが来るのを待っているのです。あなたの場合、ANR はスレッドを永久にブロックするようなものではなく、より長い操作であったと思われるので、イベントスレッドは操作終了後に回復し、あなたのトレースは ANR の後に通過しました。

ANRがどこで発生したかを検出するのは、それが恒久的なブロック(例えば、いくつかのロックを取得するデッドロック)であれば簡単ですが、一時的な遅延であれば困難です。まず、自分のコードに目を通し、危険な箇所や長く続く操作を探します。例えば、ソケットの使用、ロック、スレッドスリープ、イベントスレッド内での他のブロック操作などがあります。これらはすべて別のスレッドで行われるようにする必要があります。もし、何も問題がないようであれば、DDMS を使ってスレッドビューを有効にしてください。これは、あなたが持っているトレースと同様に、あなたのアプリケーションのすべてのスレッドを表示します。ANRを再現し、同時にメインスレッドをリフレッシュしてください。これで、ANRが発生したときに何が起こっていたのか、正確にわかるはずです。