Show a dialog in `Thread.setDefaultUncaughtExceptionHandler`

后端 未结 2 1255
再見小時候
再見小時候 2021-02-01 22:42

When my android application throw an exception, I want to show a custom dialog to tell user there is something wrong happened, so I use Thread.setDefaultUncaughtExceptionH

2条回答
  •  孤独总比滥情好
    2021-02-01 23:28

    You cannot do any UI operation from here. Just start another activity/ splash screen. Pass an intent extra to denote crash and show dialog in that activity.

        /*
         * (non-Javadoc)
         * 
         * @see
         * java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.
         * lang.Thread, java.lang.Throwable)
         */
        @Override
        public void uncaughtException(Thread t, final Throwable e) {
            StackTraceElement[] arr = e.getStackTrace();
            final StringBuffer report = new StringBuffer(e.toString());
            final String lineSeperator = "-------------------------------\n\n";
            report.append(DOUBLE_LINE_SEP);
            report.append("--------- Stack trace ---------\n\n");
            for (int i = 0; i < arr.length; i++) {
                report.append( "    ");
                report.append(arr[i].toString());
                report.append(SINGLE_LINE_SEP);
            }
            report.append(lineSeperator);
            // If the exception was thrown in a background thread inside
            // AsyncTask, then the actual exception can be found with getCause
            report.append("--------- Cause ---------\n\n");
            Throwable cause = e.getCause();
            if (cause != null) {
                report.append(cause.toString());
                report.append(DOUBLE_LINE_SEP);
                arr = cause.getStackTrace();
                for (int i = 0; i < arr.length; i++) {
                    report.append("    ");
                    report.append(arr[i].toString());
                    report.append(SINGLE_LINE_SEP);
                }
            }
            // Getting the Device brand,model and sdk verion details.
            report.append(lineSeperator);
            report.append("--------- Device ---------\n\n");
            report.append("Brand: ");
            report.append(Build.BRAND);
            report.append(SINGLE_LINE_SEP);
            report.append("Device: ");
            report.append(Build.DEVICE);
            report.append(SINGLE_LINE_SEP);
            report.append("Model: ");
            report.append(Build.MODEL);
            report.append(SINGLE_LINE_SEP);
            report.append("Id: ");
            report.append(Build.ID);
            report.append(SINGLE_LINE_SEP);
            report.append("Product: ");
            report.append(Build.PRODUCT);
            report.append(SINGLE_LINE_SEP);
            report.append(lineSeperator);
            report.append("--------- Firmware ---------\n\n");
            report.append("SDK: ");
            report.append(Build.VERSION.SDK);
            report.append(SINGLE_LINE_SEP);
            report.append("Release: ");
            report.append(Build.VERSION.RELEASE);
            report.append(SINGLE_LINE_SEP);
            report.append("Incremental: ");
            report.append(Build.VERSION.INCREMENTAL);
            report.append(SINGLE_LINE_SEP);
            report.append(lineSeperator);
    
            Log.e("Report ::", report.toString());
            Intent crashedIntent = new Intent(BaseActivity.this, SplashActivity.class);
            crashedIntent.putExtra(EXTRA_CRASHED_FLAG,  "Unexpected Error occurred.");
            crashedIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            crashedIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(crashedIntent);
    
            System.exit(0);
            // If you don't kill the VM here the app goes into limbo
    
        }
    

    Also see:

    Android UncaughtExceptionHandler that instantiates an AlertDialog breaks

    Toast not showing up in UnCaughtExceptionHandler

    How to start activity from UncaughtExceptionHandler if this is main thread crashed?

    How i do it:

    I have a BaseActivity which extends Activity, and in onCreate of the activity I set the UncaughtExceptionHandler. All my activities extend the BaseActivity instead of Activity.

    Keys

    1. You can't set the exception handler in Application.onCreate, instead, you should create a BaseActivity and set it on the onCreate method of it.
    2. After starting the SplashActivity, we should call System.exit(0)
    3. We can't hold the error instance to share it to SplashActivity, since it will be destroyed, instead, we can pass some error message or persist it in file.

提交回复
热议问题