【问题标题】:Thread's DefaultUncaughtExceptionHandler not catching exception thrown in AlertDialog onClick() method线程的 DefaultUncaughtExceptionHandler 未捕获 AlertDialog onClick() 方法中引发的异常
【发布时间】:2016-09-27 12:09:47
【问题描述】:

我在我的Activity 的onCreate() 中为当前线程设置了一个默认的UncaughtExceptionHandler,并从我的AlertDialog 的onClick() 监听器中抛出一个RunTimeException,但没有捕获到异常。我还尝试从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() 抛出的异常没有被捕获?

【问题讨论】:

    标签: java android exception-handling uncaught-exception uncaughtexceptionhandler


    【解决方案1】:

    我试图重现应用程序的行为。 DefExcHandler 实例似乎被遗漏了,因为它没有记录任何内容,但我尝试了另外两个有效的方法:断点和文件创建。

    请尝试在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();
                }
            }
        }
    }
    

    【讨论】:

    • 日志消息确实导致了问题。非常奇怪的行为
    猜你喜欢
    • 2013-02-26
    • 2021-12-26
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2015-04-22
    • 1970-01-01
    相关资源
    最近更新 更多