【Andorid】プロセス死によるクラッシュを「ガード処理」と「ADBコマンド」で封じ込める

Android

1. はじめに:バックグラウンド復帰時の「稀な」クラッシュ

アプリを操作中に別のアプリへ切り替え、しばらくして戻ったときに突然アプリが終了してしまう。この再現性の低いエラーの正体は、OSによるメモリ解放(プロセス死)です。

2. 最強のデバッグ手法:adb shell am kill

「稀に」起きる現象を待つ必要はありません。このコマンドを使えば、アプリがバックグラウンドにいる間にOSによってプロセスが殺された状態を瞬時に再現できます。

再現手順:

  1. アプリを起動し、詳細画面やビューアー画面まで進める。
  2. ホームボタンを押して、アプリをバックグラウンドへ送る。
  3. ターミナルで以下を実行: adb shell am kill faithit.image.ad_lockmovie
  4. 履歴ボタン(□)からアプリを選択して復帰。

これでクラッシュすれば、復帰時のデータ整合性に問題があります。

3. 今回の解決策:完璧な復元よりも「徹底したガード」

本来は onSaveInstanceState で全てのデータを保存・復元するのが理想ですが、パラメータが多い場合、実装コストとバグのリスクが増大します。今回は、**「データが消失していることを前提としたエラー処理」**で対応しました。

具体的な修正ポイント:インデックスの範囲チェック

プロセス復帰時に UtilCommon(Applicationクラス)のデータが空になると、検索処理が失敗して -1 を返すことがあります。これをそのままリストのアクセスに使うと ArrayIndexOutOfBoundsException で即死します。

修正コードのイメージ:

Java

// インデックスが不正(-1など)な場合は、クラッシュさせる前にガードする
mPosition = adapter.getFileNamePosition(common.getSelectName());

if (mPosition < 0 || mPosition >= adapter.getItemCount()) {
    Log.e(TAG, "データ消失を検知。安全のためリストに戻ります。");
    // クラッシュさせずに、前の画面に戻るなどの安全な処理へ誘導
    getParentFragmentManager().popBackStack();
    return;
}

4. なぜこの方法が有効か?

  • 実装がシンプル: 膨大な変数を Bundle に詰める手間が省けます。
  • 致命的なエラーを回避: FATAL EXCEPTION を防ぎ、ユーザーを「アプリが落ちた」という不快な体験から守ります。
  • メンテナンス性: どの画面でも「データがなければ安全に閉じる」というルールを徹底するだけで、堅牢なアプリになります。

5. まとめ

バックグラウンド復帰時のエラー対策に、adb shell am kill によるテストは欠かせません。 「データは消えるもの」と割り切り、適切にエラー処理(ガード)を追加していくことで、低コストで高品質なアプリを実現できます。

コメント