向上导航未启动父级 activity

Up Navigation not launching parent activity

我有两个活动 AB,其中 A 是 B 的父级。现在我显示启动 B 的通知。当我点击通知时,B 启动。然后我点击 up 按钮。当 activity A 在后台时,它可以正常工作,否则应用程序只是关闭并且不会启动 activity A.

我的设置。

我已经在 SingleTop launchMode

中将 A 声明为清单中 B 的父级
<activity
        android:name=".A"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="<packegeName>.Home" />
        </intent-filter>
    </activity>
    <activity
        android:name=".B"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:parentActivityName=".A"
        android:theme="@style/AppTheme.NoActionBar">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".A" />
    </activity>

这是通知意图:

Intent intent = new Intent(this, B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 
                                                        PendingIntent.FLAG_ONE_SHOT);

在Activity乙:

@Override
public void onCreate(Bundle savedInstanceState) {
    ....
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    ....
}

我试过的

为了调试,我尝试在 Activity B 的 onResume 中手动触发向上导航,所有这些:

1)

Intent upIntent = NavUtils.getParentActivityIntent(this);
upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    // This activity is NOT part of this app's task, so create a new task
    // when navigating up, with a synthesized back stack.
    TaskStackBuilder.create(this)
            // Add all of this activity's parents to the back stack
            .addNextIntentWithParentStack(upIntent)
            // Navigate up to the closest parent
            .startActivities();
} else {
    // This activity is part of this app's task, so simply
    // navigate up to the logical parent activity.
    NavUtils.navigateUpTo(this, upIntent);
}

2)

onNavigateUp();

3)

NavUtils.navigateUpFromSameTask(this);

但是当 Activity A 不在 Backstack 中时,其中 none 似乎可以工作,应用程序就退出了。

我搜索了 SO 和 Google(甚至 bing!)寻找答案并尝试了我能找到的所有方法,但都无济于事。由于没有错误或日志输出,我也不知道如何调试。

我们将不胜感激任何有关找出问题的解决方案或提示。

谢谢。

尝试为 Synthesize a new Back Stack for Deep Links

描述的方法

您将使用 TaskStackBuild 构建返回堆栈并在 Activity B 开始时获取 PendingIntent。

查看来自 Android Design Patterns 的 this 视频,解释很简单。

@pablobu 的回答对我有用,但我想对我发现的内容添加更多解释。

该死的那些文档令人困惑

我最初感到困惑的地方是由于 this :

If your activity provides any intent filters that allow other apps to start the activity, you should implement the onOptionsItemSelected() callback such that if the user presses the Up button after entering your activity from another app's task, your app starts a new task with the appropriate back stack before navigating up.

    if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
        // This activity is NOT part of this app's task, so create a new task
        // when navigating up, with a synthesized back stack.
        TaskStackBuilder.create(this)
                // Add all of this activity's parents to the back stack
                .addNextIntentWithParentStack(upIntent)
                // Navigate up to the closest parent
                .startActivities();
    } else {
        // This activity is part of this app's task, so simply
        // navigate up to the logical parent activity.
        NavUtils.navigateUpTo(this, upIntent);
    }

我的印象是这会为我生成 backstack。但有一点不同。

NavUtils.shouldUpRecreateTask(this, upIntent) 仅当当前 activity 在另一个应用程序的任务中时才会 return 为真。至于从通知启动,这将是错误的,因此任务堆栈构建代码不会执行。

正确的方法是在生成通知并将其作为未决意图传递时构建后台堆栈。来自 this page :

when a notification takes the user to an activity deep in your app hierarchy, you can use this code to create a PendingIntent that starts an activity and inserts a new back stack into the target task.

Intent detailsIntent = new Intent(this, DetailsActivity.class);
// Use TaskStackBuilder to build the back stack and get the PendingIntent
PendingIntent pendingIntent =
        TaskStackBuilder.create(this)
                        // add all of DetailsActivity's parents to the stack,
                        // followed by DetailsActivity itself
                        .addNextIntentWithParentStack(detailsIntent)
                        .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent);

覆盖 activity 中的 public boolean shouldUpRecreateTask(Intent targetIntent) 方法并始终 return true.