11

私のアプリケーションはどこかで強制終了を引き起こしていますが、LogCat の通常の (そして非常に有益な) スタック トレースで FATAL EXCEPTION を取得する代わりに、次の 4 行のみを受け取ります。

06-27 07:08:54.546: D/dalvikvm(14351): GC_FOR_MALLOC freed 9923 objects / 657416 bytes in 21ms
06-27 07:08:54.769: W/dalvikvm(14351): threadid=20: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: W/dalvikvm(14351): threadid=21: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: I/Process(14351): Sending signal. PID: 14351 SIG: 9

これは、LogCat にフィルターが適用されていない DEBUG モードです。

  • この動作の原因は何ですか?
  • この例外の原因を特定する方法はありますか?

更新:以下の @assylias のおかげで、実装できました:

final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
    Log.getStackTraceString(paramThrowable);

    subclass.uncaughtException(paramThread, paramThrowable);
    }
});

これらの追加された行が生成されました:

06-27 08:24:47.105: D/dalvikvm(15475): GC_FOR_MALLOC freed 13865 objects / 1435952 bytes in 45ms
06-27 08:24:47.136: I/dalvikvm(15475): threadid=15: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.136: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x45209338 (56 left)
06-27 08:24:47.140: I/dalvikvm(15475):   expanding stack end (0x45209300 to 0x45209000)
06-27 08:24:47.140: I/dalvikvm(15475): Shrank stack (to 0x45209300, curFrame is 0x4520937c)
06-27 08:24:47.159: I/dalvikvm(15475): threadid=16: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.159: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x4520c338 (56 left)
06-27 08:24:47.167: I/dalvikvm(15475):   expanding stack end (0x4520c300 to 0x4520c000)
06-27 08:24:47.167: I/dalvikvm(15475): Shrank stack (to 0x4520c300, curFrame is 0x4520c37c)
06-27 08:24:47.175: I/dalvikvm(15475): threadid=17: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.175: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x4520f338 (56 left)
06-27 08:24:47.175: I/dalvikvm(15475):   expanding stack end (0x4520f300 to 0x4520f000)
06-27 08:24:47.175: I/dalvikvm(15475): Shrank stack (to 0x4520f300, curFrame is 0x4520f37c)

これは確かにはるかに役立つ情報ですが、現在、次のことに苦労しています。

  • への呼び出しにもかかわらず、アプリケーションは現在強制終了しませんsubclass.uncaughtException()。なんで?
  • これらすべてのスタック オーバーフローの意味は何ですか? 貧弱な Android テスト デバイスに負担をかけるようなことを何をすればよいのでしょうか?
  • コードのどの部分がこれを引き起こしているかをどのように判断できますか?

更新: Log.getStackTraceString(paramThrowable);実際には何も印刷していませんでした。私が受け取った余分なプリントは、のsubclass.uncaughtException(paramThread, paramThrowable);からのものでした。完全なスタック トレースを記録する正しい方法は、Log.e(TAG, "uncaughtException", throwable)を使用することです。

今残っている唯一の問題は、例外を再スローする方法です。ただ行うthrow paramThrowable

最後の質問に答える: Eclipse では、try/catch で囲まないとスローできません。これにより、必要なのは再スローではなく、killProcess(). 問題が解決しました。

4

3 に答える 3

19

アプリの開始時にデフォルトのキャッチされていない例外ハンドラーを設定し、そこにデータを記録することができます (以下の例では Java ロガーを使用していますが、Android に簡単に移行できます)。

private static void setDefaultUncaughtExceptionHandler() {
    try {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread t, Throwable e) {
                logger.error("Uncaught Exception detected in thread {}", t, e);
            }
        });
    } catch (SecurityException e) {
        logger.error("Could not set the Default Uncaught Exception Handler", e);
    }
}
于 2012-06-27T11:46:05.000 に答える
2

これは面倒ですが、デバッガーで壊れるまでシングルステップスルーします。次に、より一般的なキャッチを追加できます

キャッチ(例外e){}

すべての例外は Exception から拡張されるため、問題をさらに診断するのに役立ちます。

もう 1 つのアイデアとして、アプリがデバイスのメモリを使い果たしている可能性があります。JVM は、JVM シャットダウン オン メモリ エラーが原因で、ユーザーに通知せずにアプリを強制終了している可能性があります。

于 2012-06-27T11:42:29.123 に答える