1

UncaughtExceptionHandlerの現在のスレッドのデフォルトを設定し、ActivityのリスナーからonCreate()a をスローしましたが、例外はキャッチされません。また、 andから例外をスローしようとしましたが、キャッチされませんでした。ただし、またはからスローされるとキャッチされます。RunTimeExceptionAlertDialogonClick()onCreateOptionsMenu()onOptionsItemSelected()onCreate()onResume()

これが私の活動です:

public class MainActivity extends AppCompatActivity implements DialogInterface.OnClickListener {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler());
        Log.d(TAG, "onCreate: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId());

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setNeutralButton("CRASH", this);
        AlertDialog dialog = builder.create();
        dialog.show();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        Log.d(TAG, "onClick: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId());
        throw new RuntimeException();
    }
}

そして、ここに私の例外ハンドラがあります:

public class DefExcHandler implements Thread.UncaughtExceptionHandler {

    private static final String TAG = "DefExcHandler";

    public DefExcHandler() {
        Log.d(TAG, "DefaultExceptionHandler: ");
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        Log.d(TAG, "Uncaught exception caught: "+ex.getMessage()+" "+ex.getCause().toString());
    }
}

アクティビティで作成したログ メッセージに基づいて、スレッドは と の場合と同じonCreate()ですonClick()

09-27 15:00:57.260 10667-10667/a.b.c D/MainActivity: onCreate: main 1
09-27 15:01:52.680 10667-10667/a.b.c D/MainActivity: onClick: main 1

onClick()onCreateOptionsMenu()またはからスローされたときに例外がキャッチされないのはなぜonOptionsItemSelected()ですか?

4

1 に答える 1

0

アプリの動作を再現してみました。何もログに記録されていないため、DefExcHandlerインスタンスは見逃されているようですが、ブレークポイントとファイルの作成という 2 つの機能を試してみました。

内にブレークポイントを設定してみてくださいuncaughtException()。コードの実行が停止すると思います。そして、ファイルをフラグとして使用して、キャッチされていない例外ハンドラーが実際に呼び出されていることを示す例を以下に書きました。

要するに、DefExcHandler.uncaughtException()呼び出されているように見えますが、Android はなんらかの理由でログを記録できません。おそらく内部競合状態です。

// Example that assures that an UncaughtExceptionHandler
// is being invoked by flagging execution with file creation.

public class MainActivity extends ... implements ... {

    private File mCrashFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mCrashFile = new File(getFilesDir(), "crash");

        // Crash file existence means the application has crashed before.
        Log.d(TAG, "crash file exists: " + mCrashFile.exists());

        // Clear crash flag.
        if (mCrashFile.exists()) {
            Log.d(TAG, "crash file delete: " + mCrashFile.delete());
        }

        Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler());

        ...

    }

    private class DefExcHandler implements Thread.UncaughtExceptionHandler {

        @Override
        public void uncaughtException(Thread thread, Throwable ex) {

            // Set crash flag.
            try {
                mCrashFile.createNewFile();
            } catch (IOException e) {
                // dunno if it really prints anything
                e.printStackTrace();
            }
        }
    }
}
于 2016-09-27T18:12:59.317 に答える