【问题标题】:singleTop Activity sometimes being created even when on top of stack即使在堆栈顶部,有时也会创建 singleTop Activity
【发布时间】:2014-12-23 02:05:52
【问题描述】:

我有一个 Activity,其 launchMode 为 singleTop(在清单中)。我的理解是,如果 Activity 是 singleTop 并且它位于 Activity 堆栈的顶部,那么使用新 Intent 启动 Activity 实际上会导致在 Activity 上调用 onNewIntent() ,而不会创建新的 Activity 实例(因此,不会调用 onCreate())。

此 Activity 运行一个显示持续通知的前台服务。选中后,此通知只会将用户带回到堆栈顶部的 Activity(没有从这个 singleTop 活动启动的活动)。 My problem is that when the notification is selected, sometimes a new instance of the Activity is created – even when it is visibly already on top of the stack.这对我的 Activity 来说是有问题的,因为它的行为对于它在后台被杀死并重新启动的情况是不同的(与刚刚使用 onNewIntent() 放在前面的情况相比)。我的服务用于呈现通知的代码如下:

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);

Intent notificationIntent = new Intent(this, MyProblematicActivity.class);
notificationIntent.putExtra(EXTRA_MY_DATA, "MyData");
stackBuilder.addNextIntent(notificationIntent);

PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext()).
        setSmallIcon(smallIconResourceId).
        setContentTitle(contentTitle).
        setContentText(contentText).
        setAutoCancel(false).
        setOngoing(true).
        setContentIntent(pendingIntent);

startForeground(MY_NOTIF_ID, notificationBuilder.build());

我说这种行为有时会发生,当它发生时,它会反复发生。例如:

  1. MyProblematicActivity 首次启动
  2. 服务启动并显示通知
  3. 已选择通知。
  4. MyProblematicActivity 再次创建(服务已启动,通知已显示)。
  5. 重复 2-4 次。

有时,在 #3 之后,调用 MyProblematicActivity 的 onNewIntent() 而不创建新实例,并且事情按预期工作。

我不知道为什么会发生这种情况。任务根目录下的状态活动是否会对我的 singleTop 活动的行为方式产生任何影响? FWIW,创建 MyProblematicActivity 的 Activity 是一个 singleTask Activity。

【问题讨论】:

  • 你终于找到问题和解决方案了吗?

标签: android android-pendingintent launchmode taskstackbuilder


【解决方案1】:

您遇到此问题是因为您使用的是TaskStackBuilder. The behaviour ofTaskStackBuilderis that it always resets the task, which means that theActivitywill be created again. Don't useTaskStackBuilderfor this, just callPendingIntent.getActivity()to get aPendingIntentto add to yourNotification`。

【讨论】:

  • 如果堆栈构建器总是重新创建东西。在应用使用期间,这没有多大意义
  • @Remario 但这并不能改变事实,那就是它正是这样做的。它构建了全新的任务堆栈!我从不使用TaskStackBuilder,我总是建议开发人员不要使用它,除非他们完全理解它的作用。
  • @Remario 您应该打开一个新问题,因为在评论中进行此讨论对其他开发人员没有用处。请准确说明您想知道什么,或者您遇到了什么问题。谢谢。
【解决方案2】:
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

将此标志添加到通知意图

【讨论】:

  • 这并不能解决问题。正在创建 Activity 的新实例并调用 onCreate()。
【解决方案3】:

我的回答与 Komal 所说的相同,但只是为了解释整个事情背后的原因,

如果您使用singleTop,则只有在您的目标活动位于堆栈顶部时才不会调用新实例,如果它不在顶部,则在onNewIntent() 中接收新意图;因此创建了新实例。

所以,

添加标志Intent.FLAG_ACTIVITY_CLEAR_TOP

如果您向上导航到当前堆栈上的某个活动,则行为由父活动的启动模式决定。如果父 Activity 具有启动模式 singleTop(或向上意图包含 FLAG_ACTIVITY_CLEAR_TOP),则父 Activity 将被带到堆栈顶部,并保留其状态。导航意图由父活动的 onNewIntent() 方法接收。如果父 Activity 具有启动模式标准(并且向上 Intent 不包含 FLAG_ACTIVITY_CLEAR_TOP),则当前 Activity 及其父 Activity 都从堆栈中弹出,并创建父 Activity 的新实例以接收导航 Intent。

Documentation

【讨论】:

  • 这并不能解决问题。正在创建 Activity 的新实例并调用 onCreate()。
猜你喜欢
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2019-06-26
  • 2011-11-25
相关资源
最近更新 更多