Thread的DefaultUncaughtExceptionHandler没有捕获AlertDialog onClick()方法中抛出的异常(Thread's DefaultUncaugh

编程入门 行业动态 更新时间:2024-10-27 06:30:11
Thread的DefaultUncaughtExceptionHandler没有捕获AlertDialog onClick()方法中抛出的异常(Thread's DefaultUncaughtExceptionHandler not catching exception thrown in AlertDialog onClick() method)

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

I set a default UncaughtExceptionHandler for the current thread in my Activity's onCreate() and throw a RunTimeException from my AlertDialog's onClick() listener but the exception is not caught. I also tried throwing the exception from onCreateOptionsMenu() and onOptionsItemSelected() and it wasn't caught. It is caught however when thrown from onCreate() or onResume().

Here's my activity:

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(); } }

And here's my exception handler:

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()); } }

Based on the log messages I make in my activity the thread is the same when in onCreate() and 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

Why is the exception not caught when thrown from onClick(), onCreateOptionsMenu() or onOptionsItemSelected()?

最满意答案

我试图重现应用程序的行为。 似乎错过了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();
            }
        }
    }
}

I tried to reproduce the application's behavior. The DefExcHandler instance seems to be missed since it isn't logging anything, but I tried two other things that worked: breakpoint and file creation.

Please try to set a breakpoint inside uncaughtException(). I believe it will stop the execution in your code. And I have written an example below that uses a file as a flag to indicate that the uncaught exception handler is really being invoked.

In sum, it seems that DefExcHandler.uncaughtException() is being called but Android can't do the logging for some unknown reason, maybe an internal race condition.

// 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();
            }
        }
    }
}

                    
                     
          

更多推荐

本文发布于:2023-07-20 20:39:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1203709.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:抛出   异常   方法   onClick   AlertDialog

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!