0

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>
na29
  • 45
  • 6
  • `RuntimeException extends Activity` you really don't want to do this, as this will most likely end up by shooting yourself in your foot in a matter of one week rather than months. Be aware that your `RuntimeExceptionActivity` doesn't change the nature of the `RuntimeException`s thrown around the code. They still won't be subclasses of Activity. – Shark Jul 18 '23 at 09:42

2 Answers2

1
  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.

Watermelon
  • 452
  • 2
  • 5
  • RuntimeException extends Activity, not Exception, so it should be a valid activity. I have to check if I have used the wrong class in the setClass call. Thank you for the reply, I will check and let you know. – na29 Jul 18 '23 at 07:43
  • I am using the right RuntimeException class, so it isn't the problem. – na29 Jul 18 '23 at 08:22
1

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);
        }
    }
viethoang
  • 111
  • 3