如果活动由同一个类实现,如何返回特定活动

Cod*_*odo 8 android android-intent

为了实现向上导航,我想回到历史堆栈上的特定活动.如果堆栈上的活动是由不同的类实现的,它就像这样工作(假设我在堆栈上有活动A,B和C,并希望返回活动A:

protected void onUpPressed() {
    Intent intent = new Intent(this, A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                  | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    startActivity(intent);
    finish();
}
Run Code Online (Sandbox Code Playgroud)

Android将弹出堆栈中的活动,直到intent指定的活动是最重要的(在这种情况下由A类实现的活动).

但是,我的应用程序在同一个类实现的堆栈上有几个活动.那是因为它们显示相同类型的数据但是针对不同的对象.它们的启动意图既指定了实现活动的类,又指定了要显示的对象(在extras包中或在data属性中).

现在我正在寻找代码再次从历史堆栈中弹出几个活动,直到匹配活动为最顶层.如果我扩展上面的代码并另外设置extras bundle或data属性,它就不起作用.Android总是匹配指定类实现的第一个活动,并且回溯得不够远.附加包和数据属性将被忽略.

protected void onUpPressed() {
    Intent intent = new Intent(this, A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                  | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.setData(Uri.parse("myapp:" + rootId));
    startActivity(intent);
    finish();
}
Run Code Online (Sandbox Code Playgroud)

那么我怎样才能回到特定的活动?Android比较哪些意图字段以确定它是否找到了所需的活动?

kup*_*sef 5

如您所述,您有一个Activity根据起始Intent显示不同的内容.好吧,为什么不碎片?

我不知道你的应用程序架构的细节,但应该很容易将Activity重构为片段.可能有一个FragmentActivity包含负责显示内容的所有片段.通过这种方式,您可以更自由地处理活动的片段堆栈.

总结的步骤:

  • 将现有的Activity(显示内容)转换为Fragment.
  • 制作FragmentActivity(将管理片段).
  • 使FragmentActivity成为"singleInstance",因此它将缓存所有"startActivity"请求,您可以在其中添加表示要显示的新内容的新片段.

您可以这样添加片段:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    // ContentFragment is the Fragment that you made from your Activity.
    // Here you can pass the intent that stores the object to show also,
    // so the parsing of the intent would be the same.
    ContentFragment fragment = ContentFragment.newInstance(intent);

    getFragmentManager()
    .beginTransaction()
    .add(fragment, null)
    .addToBackStack("id here that will be used at pop")
    .commit();
}
Run Code Online (Sandbox Code Playgroud)

你可以这样弹出一个特定的id:

getFragmentManager().popBackStack("id here",0);

该解决方案具有副作用.碎片将粘在一起,因此您不能在它们之间插入任何其他活动.这是微不足道的,但值得一提,因为它与您当前的实现不同.

我还假设您熟悉"singleInstance"和Fragments的工作原理.如果有什么不清楚,可以随意询问.

  • 好吧,你可以使用片段支持库.它包含此解决方案使用的所有内容.还是我错过了? (2认同)

egg*_*yal 3

为了实现,Android 使用以下测试FLAG_ACTIVITY_CLEAR_TOP搜索任务的活动堆栈(从上到下):

                if (r.realActivity.equals(newR.realActivity)) {
Run Code Online (Sandbox Code Playgroud)

您的问题是realActivityComponentName因此上面的比较找到了堆栈中与包和类名匹配的最顶层活动):没有针对意图执行进一步的测试,因此不可能更具体地了解该组件的哪个您希望开展的活动。

所以:

  1. 那么我怎样才能返回到特定的活动呢?

    没有本地方法可以实现这一点。您最好的选择可能是按照 @VM4 的建议手动实现一种冒泡形式。

  2. Android 会比较哪些意图字段来确定是否找到了所需的活动?

    仅组件名称。