4

アプリケーションのクラッシュを防ぐグローバル エラー ハンドラを登録する方法はありますか? クラッシュ レポートについては、Android アプリケーションからクラッシュ データを取得するにはどうすればよいですか?で説明されています。. 私が考えていた 1 つの考えは、これらのソリューションをアプリケーション コンテキストを取り込むように拡張して、特定のレポート アクティビティへのリダイレクトを作成できるようにすることでした。しかし、レポートするクラッシュが発生した時点で、アプリケーション コンテキストが有効かどうかわからない場合は?

しかし、クラッシュが発生したときにユーザーをグローバル エラー メッセージ アクティビティにリダイレクトするにはどうすればよいでしょうか。すべてのエラーをキャッチしてクラッシュを防ぐエラー ハンドラを登録する高レベルの方法はありますか? そのようなハンドラーを登録して、クラッシュを防止または存続させ、問題のエラー メッセージを表示する特定のアクティビティにユーザーをリダイレクトする方法はありますか?

エラーハンドラーへの私の変更は次のとおりです。

applicationContext1) ctx としてコンストラクターに渡すだけ

2)reportError(stackTrace)エラーメッセージページに制御を移すメソッドを追加

private void reportError(String stackTrace){
        Intent i = new Intent(ctx, DisplayErrorActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setAction("DISPLAY_ERROR_ACTIVITY");
        Bundle b = new Bundle();
        b.putString("STACKTRACE", stackTrace);

        i.putExtras(b); 
        try{
             Log.d("MyErrorHandler","reportError ctx="+ctx);
             ctx.startActivity(i); 
        } catch (Exception e) {
             Exception ex = e;
             e.printStackTrace();
        }

    }

そして、reportError以下を呼び出します。

public void uncaughtException(Thread t, Throwable e) {
        Log.d("MyUncoughtExceptionHandler", "uncoughtException ctx="+ctx);
        String timestamp=getDateTime();
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = timestamp + ".stacktrace";
        Log.d("MyexceptionHanlder","UncoughtException: "+stacktrace);
        if (localPath != null) {
            writeToFile(stacktrace, filename);
        }
        if (url != null) {
            sendToServer(stacktrace, filename);
        }
        reportError(stacktrace);
       // defaultUEH.uncaughtException(t, e);

    }

コメントを残すとdefaultUEH、通常のクラッシュ ダイアログが表示されます。それがなければ - 空白の画面。ログはErrorMessageActivity、プロセスとともに強制的に閉じられたことを示しています。

テストするために、エラー ハンドラをスレッドに登録した直後に、メイン アクティビティの create メソッドにゼロ除算を入れました。これをtry-catchブロックしてもクラッシュしませんが、グローバル エラー ハンドラはクラッシュを防げないようです。チェック済みctxで、デバッガーで有効なようです。

4

2 に答える 2

6

ACRAを実装するとき、キャッチされていない例外を受け取った後、新しいアクティビティを開始できませんでした。システムによってプロセス全体が特別な状態に切り替えられ、新しいリソースが許可されないようです。

現時点で見つけた唯一のオプションは、アプリケーションの再起動後にシステムによって保持されるステータスバー通知を送信することです。次に、ユーザーがダイアログ アクティビティを選択すると、通知によってダイアログ アクティビティのインテントがトリガーされます。

Alexey Yakovlev はこの問題をさらに詳しく調査し、UI スレッドではないスレッドでクラッシュが発生した場合に、新しいアクティビティがトリガーされる可能性があるという結論に達しました。ただし、すべてのケースでアクティビティを直接開始するための簡単な回避策は見つかりませんでした。

元のデフォルトのキャッチされていない例外ハンドラーを呼び出さずにプロセスを強制終了することで、デフォルトの強制終了ダイアログを取り除きました。

于 2011-04-21T12:36:10.860 に答える
3

あなたはsetUncaughtExceptionHandlerあなたのスレッドのためにすることができます。

于 2011-04-21T07:21:37.557 に答える