【问题标题】:Up Navigation not launching parent activity向上导航未启动父活动
【发布时间】:2016-07-01 00:53:51
【问题描述】:

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

我的设置。

我已在清单中声明 A 为 B 的父级,而 A 在 SingleTop 启动模式中

<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);

在活动 B 中:

@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 中时,这些似乎都不起作用,应用程序就退出了。

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

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

谢谢。

【问题讨论】:

  • 您提到您在 Activity B 的 onResume 中尝试了方法 1、2 和 3。我认为您应该在 onMenuItemSelected 内部执行这些操作,以便可以拦截主页图标上的单击事件。对我来说 1 看起来是正确的方法。
  • 您也可以使用 FLAG_ACTIVITY_REORDER_TO_FRONT,但我认为您所做的更正确:stackoverflow.com/a/32427484/6526330
  • @Dr.Nitpick 我在 onResume 中这样做是因为出于测试目的,因为如果不满足某个条件,我的应用程序需要立即转到父级。无论如何,我已经在onMenuItemSelected 中尝试了所有 3 个。但它是一样的。应用程序刚刚退出。
  • 该死,我希望能轻松搞定:P 只是好奇,当单击主页图标时,您在 onMenuItemSelected 中返回 true 还是 false?
  • case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true;

标签: android android-intent android-activity android-notifications


【解决方案1】:

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

该死的那些文档令人困惑

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

如果您的 Activity 提供任何允许其他应用启动 Activity 的意图过滤器,您应该实现 onOptionsItemSelected() 回调,这样如果用户在从其他应用的任务输入您的 Activity 后按下向上按钮,您的应用就会启动一个新的在向上导航之前使用适当的后退堆栈执行任务。

    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) 仅当当前活动在另一个应用程序的任务中时才会返回 true。至于从通知启动,这将是错误的,因此任务堆栈构建代码不会执行。

正确的方法是在生成通知时构建 backstack 并将其作为待处理的 Intent 传递。来自this page

当通知将用户带到应用层次结构深处的活动时,您可以使用此代码创建一个 PendingIntent 来启动活动并将新的返回堆栈插入到目标任务中。

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);

【讨论】:

    【解决方案2】:

    尝试为Synthesize a new Back Stack for Deep Links 描述的方法

    您将使用 TaskStackBuild 构建后台堆栈并在 Activity B 上启动时获取 PendingIntent。

    查看来自 Android 设计模式的 this 视频,解释很简单。

    【讨论】:

    • 非常感谢朋友。我在看wrong docs。现在完美了。
    【解决方案3】:

    覆盖活动中的public boolean shouldUpRecreateTask(Intent targetIntent) 方法并始终返回true

    【讨论】:

      猜你喜欢
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多