【问题标题】:after Android uncaughtException, ActivityManager does force stop on new process在 Android uncaughtException 之后,ActivityManager 确实强制停止新进程
【发布时间】:2017-05-30 05:51:12
【问题描述】:

我正在使用 Thread.setDefaultExceptionHandler() 尝试启动一个新活动,从而有效地重新启动应用程序。但是,ActivityManager 似乎在新应用程序启动后就杀死了它。

我已经尝试了许多实验。最成功的是这段代码,在异常处理程序中:

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);
}

在这种情况下,RestartActivity 会启动并显示,但仅持续一秒钟。然后该应用就完全消失了,Android 会显示之前的应用。

日志文件包含以下内容(注意 pid 略有不同):

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

我也尝试过在这个变体中使用 AlarmManager:

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);
}

在这种情况下,RestartActivity 根本不显示,我在 logcat 中看到这样一行:

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

是什么导致 Android 如此迫切地想要终止刚刚启动的进程?

【问题讨论】:

  • 你试过使用android.os.Process.killProcess吗?
  • 我不这么认为,但已经有一段时间了。这目前不在我的优先级列表中,因此在我尝试其他任何事情之前将需要“一段时间”。谢谢。
  • 不要使用 System.exit (1),因为它不会清理任务堆栈,也不会让操作系统有机会干净地退出您的应用程序。在此处阅读有关任务堆栈的更多信息:developer.android.com/guide/components/activities/…

标签: android android-activity uncaught-exception


【解决方案1】:

大量编辑,因为我误会了您要执行的操作。

第一个版本不起作用,因为您正在向自己的应用程序发送待处理的 Intent。仅仅因为它的待处理意图并不意味着它将在新进程中运行,这意味着无论其他应用程序调用它(例如通知的启动器),它都会被激活,就好像您自己的进程启动了该意图一样。例如,它可以访问私人活动。它实际上是在你被杀死之前在你的进程中开始的,然后它和你一起被杀死。

警报管理器根本不起作用,因为其中的待处理意图必须是广播接收器——它不接受服务或活动的意图。如果您在清单中放置一个接收器并使用一个待处理的意图,您可能可以让它工作。

【讨论】:

  • 谢谢,加布。所以,需要明确的是,您不知道有任何其他重启应用程序的方法吗?假设没有,我会尝试实现一个 BroadcastReceiver。
  • 不是随便的。这不是我曾经尝试过的事情。
  • 似乎工作正常 - 到目前为止只在一台设备上进行了测试。问题:显然,出于安全原因,在我手动启动应用程序之前,我的接收器将被忽略。也就是说,AlarmManager 将触发广播但 Android 不会启动我的接收器,除非我已经至少运行了一次应用程序。每次我尝试从调试器运行我的代码时,我的接收器永远不会启动。我必须通过从我设备上的应用程序中选择它来运行它。有没有办法让它从调试器中工作?
  • 接收器在我的 5.1 设备上根本没有发射。有什么想法吗?
  • @PeriHartman 您是如何注册您的接收器的——在 AndroidManifest 中还是在 Java 中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多