活动栈问题

4
我有两组活动,每组有3个活动(A1,B1,C1 || A2,B2,C2)。我从A1开始我的应用程序,然后 -> B1 -> C1,在这里我想要从C1跳转到 -> A2,如果我在A2按返回键,它应该退出应用程序而不是将我带回C1,然后从A2导航到 -> B2 -> C2。
所以基本上我想改变起始活动,就像我有两个应用程序在一个应用程序中,当我翻转到第二个应用程序时,我必须清除活动堆栈。这可能吗?有什么想法吗?
7个回答

1

在我看来,您已经回答了自己的问题。您写道:

所以基本上我想改变起始 Activity,就像我有两个应用程序在一个应用程序中,当我翻转到第二个应用程序时,我必须清除 Activity 栈。

我会这样做:

创建一个名为 DispatcherActivity 的 Activity,它是应用程序启动时启动的 Activity。此 Activity 是任务的根 Activity,并负责根据需要启动 A1 或 A2,但不要在自己身上调用 finish()(即:它将被 A1 或 A2 覆盖,但仍将位于 Activity 栈的根部)。

A1 中,捕获“返回”键并告诉 DispatcherActivity 像这样退出:

@Override
public void onBackPressed() {
    Intent intent = new Intent(this, DispatcherActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addExtra("exit", "true");
    startActivity(intent);
}

这将清除任务堆栈,直到根活动 (DispatcherActivity),然后使用此意图再次启动 DispatcherActivity

C1 中,要启动 A2,请执行以下操作:

Intent intent = new Intent(this, DispatcherActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addExtra("A2", "true");
startActivity(intent);

这将清除任务堆栈,直到根活动 (DispatcherActivity),然后使用此意图再次启动 DispatcherActivity

DispatcherActivity 中,在 onCreate() 中,您需要根据意图中的额外信息确定要执行的操作,如下所示:

Intent intent = getIntent();
if (intent.hasExtra("exit")) {
    // User wants to exit
    finish();
} else if (intent.hasExtra("A2")) {
    // User wants to launch A2
    Intent a2Intent = new Intent(this, A2.class);
    startActivity(a2Intent);
} else {
    // Default behaviour is to launch A1
    Intent a1Intent = new Intent(this, A1.class);
    startActivity(a1Intent);
}

A2中,拦截“返回”键,并使用与A1中相同的onBackPressed()覆盖来告诉DispatcherActivity退出。
注意:我刚刚输入了这段代码,所以我还没有编译它,可能不完美。你的结果可能会有所不同;-)

+1 鼓励你的努力,需要时间来检查它,但如果我在达到 C1 之前决定跳到 A2,这是否也适用? - Hesham Saeed
当然可以。在B1中,您只需将Intent发送到DispatcherActivity并告诉它启动“A2”。这就是为什么您应该以这种方式做的原因。它非常灵活,而且您不需要太多额外的代码。 - David Wasser
如果我的应用程序有一个启动画面,必须在开始时显示它,我该如何实现呢?因为我必须先进入SplashActivity,然后才能进入DispatcherActivity。还是有其他的解决方法吗?谢谢。 - Hesham Saeed
没问题。启动画面是你开始的第一个活动(即:在清单中有action.MAINcategory.LAUNCHER)。它完成自己需要做的事情,然后启动DispatcherActivity并在自身上调用finish()。现在只有DispatcherActivity在活动堆栈中。其余部分按照我描述的方式工作。 - David Wasser

0

这不对。使用 noHistory 将阻止用户正常从 A1->B1->C1 和从 A2->B2->C2 导航。错误的方法。 - David Wasser

0

尝试使用此意图启动A2活动 - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


这个不起作用。为了让它工作,A2必须已经在活动堆栈中(在根处),但实际上它并没有。 - David Wasser
是的,你可能是对的。我得再查一下文档。 - Vinay W

0

使用onBackPressed和finish方法来处理此问题。

在启动其他活动之前,最好使用finish()方法关闭当前活动。

如果您想在按下返回键时返回上一个活动,请重写onBackPressed方法并调用特定的意图。

在A2活动中,在onBackPressed方法中添加finish方法(不要在此处调用上一个活动)。这是其中一种方法。


0

您可以在Activity A2中检查按下的按钮,如果是返回按钮,则可以关闭应用程序。您可以在A2中使用以下方法:

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            this.finish();
        }
        return super.onKeyDown(keyCode, event);
    }

这不起作用。在A2中调用 finish() 不会关闭应用程序,它只会完成A2,然后返回任务中的上一个活动(可能是C1)。 - David Wasser
@DavidWasser,您可以在onKeyDown()方法中关闭所有活动以使应用程序关闭。https://dev59.com/jm035IYBdhLWcg3wYe8F - Antrromet

0

在从活动C1传递Intent到A2时,请使用以下方式:

Intent intent=new Intent(C1.this,A2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

在您的活动A2中,通过重写返回按钮

 @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        A2.this.finish();
    }
    return super.onKeyDown(keyCode, event);
}

这个不起作用。要使其工作,A2必须已经位于活动堆栈中(在根处),但实际情况是它不在那里。 - David Wasser

0

FLAG_ACTIVITY_CLEAR_TOP 不是你要找的。 我认为你要找的是:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

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