如果提供了清除顶部和单个顶部标志,则在活动被杀死后意图未正确恢复

时间:2013-02-13 12:13:26

标签: android android-intent

在我的应用程序中,有一个使用FLAG_ACTIVITY_SINGLE_TOPFLAG_ACTIVITY_CLEAR_TOP标志开始的活动,因为我想确保该活动的只有一个实例位于堆栈顶部,所有活动都位于顶部旧实例的关闭。到目前为止一切都很好。

接下来,我想测试活动是否在多次创建并连续销毁后正确恢复。我会在调用Activity.setIntent()时使用Activity.onNewIntent()手动设置意图,以便Activity.getIntent()返回最近的意图。为了测试我在开发人员选项中激活了“不要保持活动”选项,但重新创建活动时Activity.getIntent()返回的意图是创建它的第一个意图而不是最多最近的一个。

这种情况发生在JB和ICS上,我还没有在旧版本上测试过。我做错了什么,或者我误解了文档中的内容?

2 个答案:

答案 0 :(得分:17)

如果您在应用程序位于前台时终止该应用程序,则这与Android杀死您的应用程序时不同(仅当您的应用程序在后台时才会执行此操作)。如果您杀了然后重新启动应用程序,就像从头开始重新启动它。这里没有“恢复”。如果您将日志记录添加到onCreate(),则应该会在杀死并重新启动应用后看到,传递给Bundle的{​​{1}}为空。

不幸的是,很难模拟Android杀死你的应用时会发生什么。

编辑:OP发表评论后添加了更多内容

以下是用于讨论目的的具体示例。首先没有开发者选项“不要保留活动”:

  • onCreate()是根活动
  • 我们开始ActivityA
  • ActivityA被称为
  • ActivityA.onCreate()现在开始ActivityA
  • ActivityB被调用(活动堆栈现在包含ActivityB.onCreate() - > ActivityA
  • ActivityB使用ActivityB和额外的“foo”
  • 启动ActivityA 使用包含FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP的{​​{1}}和额外的“foo”来调用
  • ActivityA.onNewIntent() 由于活动堆栈已被清除回Intent
  • ,因此会调用
  • FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP

现在,让我们做同样的事情,但启用开发人员选项“不要保持活动”(我在粗体中突出显示与前一个场景不同的内容):

  • ActivityB.onDestroy()是根活动
  • 我们开始ActivityA
  • ActivityA被称为
  • ActivityA现在开始ActivityA.onCreate()
  • ActivityA被调用(活动堆栈现在包含ActivityB - > ActivityB.onCreate()
  • 由于ActivityA已停止,Android会销毁它并致电ActivityB
  • 注意:活动堆栈仍包含ActivityA - > ActivityA.onDestroy(),即使此时没有ActivityA的实例。 Android会记住所有州
  • ActivityB使用ActivityA和额外的“foo”
  • 启动ActivityB
  • 由于Android没有重新激活ActivityA的实例,因此需要创建一个实例,因此确实如此...
  • FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP被调用的ActivityA与创建ActivityA.onCreate()的原始实例时所调用的Intent相同(即:LAUNCH意图没有标记且没有附加内容)
  • 使用包含ActivityA的{​​{1}}和额外的“foo”来调用
  • ActivityA.onNewIntent() 由于活动堆栈已被清除回Intent
  • ,因此会调用
  • FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP

这里需要注意的重要一点是Android在创建活动实例时始终会调用ActivityB.onDestroy()。可以把它想象成ActivityA构造函数。如果Android必须重新创建onCreate()的实例,因为该进程被终止或活动被销毁,那么它将实例化一个新对象,然后调用Activity然后(如果需要)它将调用{ {1}}。

当您致电Activity时,这实际上并未更改Android保存和恢复的onCreate()。这只会更改将从onNewIntent()调用返回的内存setIntent()

我希望现在更清楚了。如果没有,请告诉我。

答案 1 :(得分:3)

不确定您是否找到了解决方案,但是要覆盖目标活动的onNewIntent(Intent theNewIntent)方法&调用setIntent(theNewIntent)解决了它。

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    /*
     * This overrides the original intent.
     */      
    setIntent(intent);
}