TaskStackBuilder和后退栈的额外参数

40

我正在尝试使用TaskStackBuilder和通知一起创建返回栈,以便通过后退按钮进行导航。我的应用程序通常流程如下:

  1. 从启动器启动Activity A。
  2. 用户从A中选择一个项目,该项目使用extras启动B。
  3. 用户从B中选择一个项目,该项目使用extras启动C。

有时,在用户不使用我的应用程序时进行后台更新后,我会生成一个通知。如果他们单击此通知,它将跳过A和B而启动Activity C。我正在尝试遵循设计指南并创建返回栈,因此当他们按下后退按钮时,它将转到Activity B而不是主屏幕。我的问题是Activity B需要在启动意图中使用extra来告诉它从数据库中获取什么。

我的当前TaskStackBuilder代码:

TaskStackBuilder sBuilder = TaskStackBuilder.create( this );
sBuilder.addParentStack( ActivityC.class );
sBuilder.addNextIntent( launchIntent );

pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_ONE_SHOT );
点击通知可以成功启动活动C,但是当我按后退键时,由于Activity B不知道要请求什么ID,我的ContentProvider抛出了一个IllegalArgumentException异常。有没有办法将这个附加信息添加到返回堆栈中,或者说我现在陷入了困境?

点击通知可以正常启动Activity C,但是按下返回键时,由于Activity B不知道要请求哪个ID,所以我的ContentProvider会抛出IllegalArgumentException异常。是否有任何方法将此附加到返回堆栈中或我是否无能为力?

3个回答

58
这行内容:
sBuilder.addParentStack( ActivityC.class );

AndroidManifest.xml中,<meta-data>标签声明的所有ActivityC的父级都会被添加。我不知道它是什么,我没有使用过它。我怀疑你不需要它。

这行代码将intent添加到数组中:

sBuilder.addNextIntent(launchIntent);

然后,意图数组用于创建PendingIntent,可能使用PendingIntent.getActivities,我找不到实现方式,然后在某个地方使用Context.startActivities启动。

我认为您只需要创建一组意图,您可以在其中添加额外的内容:

Intent activityA = new Intent(context, ActivityA.class);
activityA.putExtra(key, valueA);
Intent activityB = new Intent(context, ActivityB.class);
activityB.putExtra(key, valueB);
Intent activityC = new Intent(context, ActivityC.class);
activityC.putExtra(key, valueC);

将它们添加到构建器中:
sBuilder.addNextIntent(activityA);
sBuilder.addNextIntent(activityB);
sBuilder.addNextIntent(activityC);
pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_ONE_SHOT );

我还没有测试过它,这只是我的快速研究结果,如果我错了,希望有人能纠正我。


有趣的方法,我甚至没有想过尝试。我会试一试看它是否有效,可能需要几天时间,但我会让你知道的。谢谢你的想法! - Khantahr
我不得不删除addParentStack,然后我得到了我发送的额外内容。奇怪的是,使用addParentStack的代码来自谷歌的示例。 - Gavriel
1
如果我使用PendingIntent.FLAG_UPDATE_CURRENT而不是PendingIntent.FLAG_ONE_SHOT,那么从C活动返回按钮点击无法导航到B活动。为什么? - dev1993

14

我找到了另一种解决这个问题的方法:使用方法 TaskStackBuilder.editIntentAt(int)

例子:

Intent intentC = new Intent(context, ActivityC.class);
intentC.putExtra(key, valueC);

TaskStackBuilder sBuilder = TaskStackBuilder.create(this)
    .addParentStack(ActivityB.class)
    .addParentStack(ActivityC.class)
    .addNextIntent(intentC);

Intent intentA = sBuilder.editIntentAt(0);
intentA.putExtra(key, value);
Intent intentB = sBuilder.editIntentAt(1);
intentB.putExtra(key, value);

当通知被点击时,我无法在ActivityA端检索Intent extra。:( - Muhammad Ahmed AbuTalib

9

我曾经也为此苦恼过。我的研究得出了以下解决方案(与@pawelzieba非常相似,但删去了一个重要的部分):

Intent activityA = new Intent(context, ActivityA.class);
activityA.putExtra(key, valueA);
Intent activityB = new Intent(context, ActivityB.class);
activityB.putExtra(key, valueB);
Intent activityC = new Intent(context, ActivityC.class);
activityC.putExtra(key, valueC);

TaskStackBuilder sBuilder = TaskStackBuilder.create(this)
    .addNextIntent(activityA);
    .addNextIntent(activityB);
    .addNextIntent(activityC);
PendingIntent pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT );

请注意,您不应该使用父级关联修改您的清单,并且您不希望使用:
sBuilder.addParentStack( ActivityC.class );

否则,你会在新创建的任务中得到重复的 ActivityA 和 ActivityB,这些活动没有附带任何意图。如果您不需要传递带有额外信息的意图,则可以在清单中添加父关联并调用 addParentStack()。

你说得对,那行代码添加了一个没有额外捆绑包的重复堆栈。谢谢! - X.Y.

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