即使在堆栈顶部,有时也会创建singleTop Activity

时间:2014-12-23 02:05:52

标签: android android-pendingintent launchmode taskstackbuilder

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

此活动运行显示正在进行的通知的前台服务。选中此选项后,此通知只会将用户带回堆栈顶部的活动(此singleTop活动未启动任何活动)。我的问题是,当选择通知时,有时会创建一个新的Activity实例 - 即使它已明显位于堆栈顶部。这对我的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个前言。
  6. 偶尔,在#3之后,调用MyProblematicActivity的onNewIntent()而不创建新实例,并且事情按预期工作。

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

3 个答案:

答案 0 :(得分:1)

您遇到此问题,因为您正在使用TaskStackBuilder. The behaviour of TaskStackBuilder is that it always resets the task, which means that the活动will be created again. Don't use TaskStackBuilder for this, just call PendingIntent.getActivity()to get a PendingIntent to add to your Notification`。

答案 1 :(得分:0)

notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

将此标志添加到通知意图

答案 2 :(得分:0)

我正在回答Komal所说的相同的事情,但只是为了解释这件事背后的原因,

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

所以,

添加标记Intent.FLAG_ACTIVITY_CLEAR_TOP

  

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

Documentation