onNewIntent()生命周期和已注册的监听器

163

我正在使用singleTop Activity通过onNewIntent()接收来自搜索对话框的意图。

我注意到的是,在onNewIntent()之前会调用onPause(),然后再调用onResume()。具体如下:

  • 搜索对话框被激活
  • 搜索意图被发送到Activity
  • onPause()
  • onNewIntent()
  • onResume()

问题在于,我在onResume()中注册了监听器,并在onPause()中将其删除,但它们在onNewIntent()调用中仍然需要。是否有一种标准的方法使这些监听器可用?

2个回答

323

onNewIntent() 是专门为单个位于堆栈中的singleTop活动作为入口点而设计的,因此无法调用onCreate()。从活动生命周期的角度来看,因此需要在调用onNewIntent()之前调用onPause()。我建议您重新编写活动以不使用onNewIntent()内部的这些侦听器。例如,大多数情况下我的onNewIntent()方法看起来像这样:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // getIntent() should always return the most recent
    setIntent(intent);
}

通过使用getIntent()onResume()中执行所有设置逻辑。


@Rodja,请您评论一下这个问题:https://dev59.com/82Ik5IYBdhLWcg3wp_iM#19092683?noredirect=1#19092683 - Developer
5
与原问题相关:请记住,如果您将处理搜索“Intent”的代码移入“onResume()”,则您的Activity每次恢复时都会尝试执行搜索,这可能不是您想要的行为。 - Tony Chan
1
Rodja说:从活动生命周期的角度来看,在调用onNewIntent()之前,因此需要调用onPause()。Android没有必要这样设计。您的活动已经通过恢复()完成了其生命周期。安卓并不需要调用onPause()然后再次调用onResume()。如果应用程序已恢复,则操作系统可以简单地调用onNewIntent()并保持在恢复状态。 - Sani Elfishawy
你说过,“singleTop activities which already run somewhere else in the stack”,但是根据文档,singleTop activity 总是存在于历史堆栈的顶部。这里是链接:[http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_SINGLE_TOP] - Kaveesh Kanwal
@Rodja:语句“如果活动已经在历史堆栈的顶部运行,则不会启动该活动”意味着如果该活动已经在堆栈的顶部存在,则不会启动该活动。我不明白你为什么以如此不同的方式关注单词IF - Kaveesh Kanwal
显示剩余6条评论

17

注意:从另一个生命周期方法调用生命周期方法并不是一个好的做法。在下面的示例中,我试图实现无论您的 Activity 类型如何,都会始终调用 onNewIntent。

对于 singleTop/Task 活动,除了第一次创建活动时调用 onCreate 之外,onNewIntent() 总是会被调用。此时,onCreate 被调用,为这个线程提供了一些解决方案。

您可以通过将其放入 onCreate 方法中来调用 Intent 处理程序,例如:

@Override
public void onCreate(Bundle savedState){
    super.onCreate(savedState);
    handleIntent(getIntent());
}

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

protected void handleIntent(Intent intent) {
  //code
}

63
直接调用生命周期方法通常不是一个好主意,对吧?也许看似无害,但是可能会导致onNewIntent()的某些基本实现假定已经调用了onPause()。更安全的方式是将应用程序代码封装在一个可从两个位置调用的方法中。 - BernalKC
13
同意。使用这种方法时我们遇到了一些边缘情况,最好避免。 - Saad Farooq
3
是的,我也同意避免这样做...这是为那些想要在onCreate中调用onNewIntent的人准备的。 - Pawan Maheshwari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接