クラッシュ

Android アプリは、未処理の例外またはシグナルが原因で予期しない終了が発生するとクラッシュします。Java または Kotlin で記述されたアプリは、Throwable クラスによって表される未処理の例外をスローした場合にクラッシュします。マシンコードまたは C++ で記述されたアプリは、実行中に SIGSEGV などの未処理のシグナルが発生した場合にクラッシュします。

アプリがクラッシュすると、Android はアプリのプロセスを終了し、アプリが停止したことをユーザーに知らせる図 1 のようなダイアログを表示します。

Android デバイスでのアプリのクラッシュ
図 1. Android デバイスでのアプリのクラッシュ。

アプリは、フォアグラウンドで実行されていない場合でも、クラッシュすることがあります。バックグラウンドで実行されるブロードキャスト レシーバやコンテンツ プロバイダを含め、あらゆるアプリ コンポーネントがアプリのクラッシュを引き起こす可能性があります。操作中ではないアプリがクラッシュすると、たいていのユーザーは困惑します。

アプリでクラッシュが発生する場合、このページのガイダンスが問題の診断と解決に有用です。

クラッシュを診断する

アプリがクラッシュしていることを把握したら、クラッシュを診断します。クラッシュの解決は時として困難です。しかし、クラッシュの根本原因を特定できれば、ほとんどの場合は解決策を見つけられます。

アプリのクラッシュが発生する状況はさまざまです。null 値または空の文字列の検出のように原因が明らかな場合もありますが、無効な引数が API に渡された、またはマルチスレッド化されたインタラクションが複雑すぎるなど、わかりにくい原因による場合もあります。

Android でクラッシュが発生すると、スタック トレースが生成されます。スタック トレースとは、クラッシュの時点までにプログラムで行われた関数呼び出しを順番にネストしたスナップショットです。クラッシュのスタック トレースは Android Vitals で確認できます。

スタック トレースの読み方

クラッシュを解決するには、まずクラッシュの発生場所を特定します。Play Console または logcat ツールの出力を使用している場合は、レポート詳細で参照可能なスタック トレースを使用できます。スタック トレースを参照できない場合は、アプリを手動でテストするか、クラッシュを経験しているユーザーに協力を依頼して、logcat の使用中にローカルでクラッシュを再現する必要があります。

次のトレースは、Jetpack Compose を使用して記述されたアプリのクラッシュの例を示しています。

--------- beginning of crash
AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.developer.crashsample, PID: 3686
java.lang.NullPointerException
    at com.android.developer.crashsample.ComposableSingletons$MainActivityKt.lambda$0(MainActivity.kt:27)
    at androidx.compose.foundation.ClickableNode.handleUpEvent(Clickable.kt:958)
    at androidx.compose.foundation.ClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:895)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:446)
    at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:181)
    at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:118)
    at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:2650)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2969)
    at android.app.Activity.dispatchTouchEvent(Activity.java:4683)
    at android.os.Looper.loop(Looper.java:398)
    at android.app.ActivityThread.main(ActivityThread.java:9569)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:918)

スタック トレースには、クラッシュのデバッグに不可欠な、次の 2 つの情報が表示されます。

  • スローされた例外のタイプ。
  • 例外がスローされたコードのセクション。

一般的に、スローされた例外のタイプは、何が問題かを知るための強力なヒントになります。スローされたのが IOException か、OutOfMemoryError か、またはそれ以外かを確認して、該当する例外クラスに関するドキュメントを参照します。