Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 415
Peri Hartman Avatar asked Mar 21 '26 13:03

Peri Hartman


1 Answers

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.

like image 194
Gabe Sechan Avatar answered Mar 23 '26 03:03

Gabe Sechan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!