Search code examples
androidandroid-activityuncaught-exception

after Android uncaughtException, ActivityManager does force stop on new process


I'm using Thread.setDefaultExceptionHandler() to try to start a new activity, effectively restarting the app. However, it appears that the ActivityManager is killing the new app process just after it gets started.

I've tried a number of experiements. The most successful was this code, in the exception handler:

public void handleUncaughtException (Thread thread, Throwable e)
{
  Intent intent = new Intent (getBaseContext (), RestartActivity.class);
  intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP |
                   Intent.FLAG_ACTIVITY_CLEAR_TASK |
                   Intent.FLAG_ACTIVITY_NEW_TASK);

  PendingIntent pending =
    PendingIntent.getActivity (getBaseContext (), 0, intent, PendingIntent.FLAG_ONE_SHOT);

  try {
    pending.send ();
  }
  catch (PendingIntent.CanceledException e1) {
    logE ("send pending intent:" + e1); // logE is a wrapper for Log.e().
  }

  System.exit (1);
}

In this case, the RestartActivity starts and displays, but only for a second. Then the app is completely gone and Android displays whatever was the prior app.

The log file contains this (note the pids are slightly different):

05-29 22:46:28.429 1465-3665/? I/ActivityManager: Force stopping com.perinote.crashtest appid=10170 user=0: from pid 14484
05-29 22:46:28.429 1465-3665/? I/ActivityManager: Killing 14486:com.perinote.crashtest/u0a170 (adj 0): stop com.perinote.crashtest

I've also tried using AlarmManager, in this variant:

public void handleUncaughtException (Thread thread, Throwable e)
{
  Intent intent = new Intent (getBaseContext (), RestartActivity.class);
  intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP |
                   Intent.FLAG_ACTIVITY_CLEAR_TASK |
                   Intent.FLAG_ACTIVITY_NEW_TASK);

  PendingIntent pending =
    PendingIntent.getActivity (getBaseContext (), 0, intent, PendingIntent.FLAG_ONE_SHOT);

  AlarmManager alarm = (AlarmManager)getSystemService (Context.ALARM_SERVICE);
   alarm.set (AlarmManager.RTC, System.currentTimeMillis () + 3000, pending);

  System.exit (1);
}

In this case, RestartActivity doesn't display at all, and I see a line in the logcat like this:

05-29 22:06:46.841 1465-11842/? I/ActivityManager: Force stopping com.perinote.crashtest appid=10170 user=0: from pid 12551

What is causing Android to so badly want to kill the process that just started?


Solution

  • Heavily edited as I mistook what you were trying to do.

    The first version doesn't work because you're sending a pending intent to your own application. Just because its a pending intent doesn't mean it will be run in a new process, it means that whatever other app calls it (such as the launcher for notifications) it will be activated as if your own process launched the intent. So it can access private activities, for example. Its actually started in your process before you're killed, then it gets killed with you.

    The, the alarm manager doesn't work at all because the pending intent in it must be to a BroadcastReceiver- it doesn't accept one to a Service or Activity. If you put a receiver in your manifest and use a pending intent to that, you can probably get it to work.