UncaughtExceptionHandler can't start activities

139 Views Asked by At

I can't find a solution to this problem. I have created an Application class, where I am setting the default uncaught exception handler, and I want to start an activity from there when an exception occurrs:

public final class Application extends android.app.Application {
    public Application() {
        Thread.setDefaultUncaughtExceptionHandler(new Application.UncaughtExceptionHandler());
    }
    static Context context;

    static final class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        @Override
        public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
            context.startActivity(new Intent()
                            .setClass(context, RuntimeException.class)
                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            /*.putExtra("u", true).putExtra("e", e)*/);
            //System.exit(0);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
}

This is the RuntimeException class, it is also defined in the manifest:

public class RuntimeException extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a_exception);

        Bundle extras = getIntent().getExtras();
        boolean uncaught = extras.getBoolean("u", false);
        Throwable exception = (Throwable) extras.get("e");

        String exceptionType;
        if (uncaught) exceptionType = "Uncaught exception:\n"; else exceptionType = "Exception:\n";

        TextView msg = findViewById(R.id.ex_msg);
        msg.setText(exceptionType + exception.getLocalizedMessage());
    }
}

This is the manifest:

<application
        android:name=".application.Application"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyTheme"
        tools:targetApi="31">
        <activity
            android:name=".activity.Launcher"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.FileList"/>
        <activity android:name=".activity.RuntimeException"/>
    </application>
2

There are 2 best solutions below

0
viethoang On BEST ANSWER

Should kill process after calling startActivity

static final class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        @Override
        public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
            context.startActivity(new Intent()
                            .setClass(context, RuntimeException.class)
                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            /*.putExtra("u", true).putExtra("e", e)*/);
             android.os.Process.killProcess(android.os.Process.myPid());
             System.exit(0);
        }
    }
2
Watermelon On
  1. You need to call setClass on Intent with valid Activity class to actually start an Activity not Exception.class

  2. when main thread's uncaught exception occurs, the main event loop is terminated, so when the main thread's exception handler returns, main thread exit and program terminates.

detail of 2. android main Thread uncaught exception handler is called after the main thread's event loop exit. Which means that main Thread eventually return, and OS will kill the process.