Android向けの最もシンプルなエラーピッカーの作成

アプリケーションを開発するとき、コードや環境でエラーが発生することは避けられません。 そして、そのようなエラーがテスト用の電話/エミュレーターではなく実際のユーザーで発生するのは非常に悲しいことです。 ベータテスターの友達でなく、誰が何をどこで落ちたのかを実際に説明できる人がいなければ、さらに悲しいことです。



通常、アプリケーションが突然クラッシュした場合、Androidはアプリケーションの詳細なスタックトレースとバージョン情報があるエラーレポートの送信を提案します。 残念ながら、ユーザーは常に「レポートを送信」ボタンをクリックするわけではありません。また、アプリケーションや市場にないアプリケーションをデバッグする場合、そのような機能は完全に利用できません。



どうする? 例外を処理するJavaの能力は、未処理のものも含めて救助に来ます。







Threadクラスには、静的なsetDefaultUncaughtExceptionHandlerメソッドがあります。 このメソッドを使用すると、キャッチされない例外に対して独自のハンドラクラスを設定できます。 ハンドラクラスは、 Thread.UncaughtExceptionHandlerインターフェイスを実装する必要があります。 ハンドラフレームワークは次のようになります。

public class TryMe implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable throwable) { Log.d("TryMe", "Something wrong happened!"); } }
      
      





唯一のメソッドは、入力としてThread(例外が発生したスレッド)とThrowable(例外自体)を受け入れます。 上記の実装では、ログにメッセージが詳細なしで表示されるだけです...それを使用してみましょう...

 public class MainActivity extends MapActivity { @Override public void onCreate(Bundle savedInstanceState) { Thread.setDefaultUncaughtExceptionHandler(new TryMe()); Integer a=1; if(true) a=null; int x = 6; x=x/a; // Exception here! } }
      
      





上記のコードを実行すると、ログにメッセージが表示され、黒い画面が表示されます。 独自のハンドラーをインストールすることで、通常のAndroid OSハンドラーを削除し、アプリケーションを閉じることはできなくなりました。



状況を修正する

 public class TryMe implements Thread.UncaughtExceptionHandler { Thread.UncaughtExceptionHandler oldHandler; public TryMe() { oldHandler = Thread.getDefaultUncaughtExceptionHandler(); //     } @Override public void uncaughtException(Thread thread, Throwable throwable) { Log.d("TryMe", "Something wrong happened!"); if(oldHandler != null) //    ... oldHandler.uncaughtException(thread, throwable); // ...  } }
      
      





これで、ログのメッセージと通常のシステムメッセージの両方が表示されます。



Activityでハンドラーを設定するのは不便です。 それはインストールされますが、すべてのスレッドが、アクティビティはいくつかの同じ開始することができますが。 また、サービスも存在する可能性があります...この場合、アプリケーションの初期化時にハンドラーをインストールするのが最善です。 このようなもの:

 public class MyApplication extends Application { @Override public void onCreate() { Thread.setDefaultUncaughtExceptionHandler(new TryMe()); super.onCreate(); } }
      
      





この場合、マニフェストに新しいアプリケーションクラスを登録することを忘れないでください。 このようなもの:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.package"> <application android:name="MyApplication" ...
      
      





これで、アプリケーションの起動時に(どのコンポーネントに関係なく)、例外ハンドラーがインストールされます。



もちろん、ログにメッセージを表示することは重要ではありません。 より多くの情報を収集する必要があります。 アプリのバージョンは? どの例外が処理されませんか? 致命的な人の解放につながった他の例外は何ですか? どのスレッドで? スタックは何でしたか? この情報はすべて入手可能です。 上記のすべての情報を受信して​​SDカードに保存する最も単純な例外ハンドラーのコードは、 GitHubで入手できます



上記の実装は、未処理の例外に関する情報を、stackcard-dd-MM-yy.txtという形式のファイルの/Android/data/your.app.package.name/files/フォルダーにあるSDカード上のファイル( 開発ガイドの指示どおり)に保存します。 アプリケーションマニフェストで作業するには、許可WRITE_EXTERNAL_STORAGEが必要です。



当然、これが唯一のそのようなソリューションではありません。



Flurry-モバイルアプリケーションの分析には、独自のエラーハンドラが含まれています。 ACRAは、エラーデータを収集してGoogleDocsに投稿するAndroid用のライブラリです。 Android-remote-stacktrace-同様のライブラリで、ユーザースクリプトレシーバーにデータを送信します。 また、このStackOverflowの質問に関する多くの有用な情報を入手できます。



All Articles