400

我的应用程序在用户第一次运行应用程序时显示注册活动,如下所示:

  1. ActivitySplashScreen(欢迎来到游戏,注册账号?)
  2. ActivitySplashScreenSignUp(很好,填写此信息)
  3. ActivityGameMain(主游戏画面)

因此,当用户单击每个屏幕上的按钮时,活动会以完全相同的顺序相互启动。

当用户从活动 #2 转到 #3 时,是否可以将 #1 和 #2 从历史堆栈中完全擦除?我想要这样,如果用户在#3,并点击后退按钮,他们只是去主屏幕,而不是回到启动屏幕。

我想我可以通过任务来完成这个(即在#3上开始一个新任务)但想看看是否有更简单的方法,

谢谢

4

15 回答 15

659

您可以通过在文件的相关条目中设置android:noHistory 属性来实现此目的。例如:"true"<activity>AndroidManifest.xml

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />
于 2010-12-07T12:32:33.740 回答
139

您可以使用转发从活动堆栈中删除前一个活动,同时启动下一个活动。 APIDemos 中有一个这样的例子,但基本上你所做的只是在调用finish()之后立即调用startActivity()

于 2009-12-14T04:20:44.263 回答
54

是的,看看Intent.FLAG_ACTIVITY_NO_HISTORY

于 2009-12-14T10:30:58.223 回答
24

这可能不是理想的方法。如果有人有更好的方法,我将期待实施它。以下是使用 pre-version-11 sdk 完成此特定任务的方法。

在您想在时间清楚时离开的每个班级中,您需要执行以下操作:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

那么需要从堆栈中触发弹出链的那个只需要在您想要启动它时调用它:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

然后活动不在堆栈上!
请记住,您可以启动一个活动,然后开始清理它,执行不遵循单个(ui)线程。

于 2011-05-13T03:04:12.220 回答
23

在 API 11 之前有效的一种方法是先启动ActivityGameMain,然后在该onCreateActivity 中启动您的ActivitySplashScreenActivity。当ActivityGameMain您为启动太早调用 startActivity 时,不会出现。

然后,您可以在启动时ActivityGameMain通过在 Intent 上设置这些标志来清除堆栈:

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

您还必须将其添加到 ActivitySplashScreen:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

因此,按下该活动不会回到您的ActivityGameMain.

我假设您不希望启动画面返回到任何一个,为了实现这一点,我建议将其设置为noHistory您的AndroidManifest.xml. 然后将goBackPressed代码放在您的ActivitySplashScreenSignUp班级中。

但是我找到了一些方法来打破这个。显示时从通知启动另一个应用程序ActivitySplashScreenSignUp并且不重置返回历史记录。

解决这个问题的唯一真正方法是在 API 11 中:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
于 2012-03-08T18:48:33.983 回答
20

我用这种方式。

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);
于 2015-09-15T01:32:20.953 回答
8

I know I'm late on this (it's been two years since the question was asked) but I accomplished this by intercepting the back button press. Rather than checking for specific activities, I just look at the count and if it's less than 3 it simply sends the app to the back (pausing the app and returning the user to whatever was running before launch). I check for less than three because I only have one intro screen. Also, I check the count because my app allows the user to navigate back to the home screen through the menu, so this allows them to back up through other screens like normal if there are activities other than the intro screen on the stack.

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}
于 2012-03-03T17:33:03.023 回答
7

在清单中,您可以添加:

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

你也可以打电话

finish()

调用 startActivity(..) 后立即

于 2017-02-08T11:02:58.153 回答
6

只需noHistory="true"清单文件中设置。它使活动从后台堆栈中删除。

于 2015-12-15T08:16:15.397 回答
4

为时已晚,但希望它有所帮助。大多数答案都没有指向正确的方向。这种事情有两个简单的标志。

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

来自 Android 文档:

public static final int FLAG_ACTIVITY_CLEAR_TASK 在 API 级别 11 中添加

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

在活动开始之前要清除的活动。也就是说,该活动成为一个空任务的新根,并且所有旧活动都已完成。这只能与 FLAG_ACTIVITY_NEW_TASK 结合使用。

于 2018-08-02T10:27:52.793 回答
4

没有人提到这个优雅的解决方案真是太疯狂了。这应该是公认的答案。

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

这里的关键是intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 用于中介Activity。一旦该中间链接被破坏,DashActivity它将成为堆栈中的第一个和最后一个。

android:noHistory="true"是一个糟糕的解决方案,因为它在依赖Activity作为回调时会导致问题,例如onActivityResult. 这是推荐的解决方案,应该被接受。

于 2018-05-03T11:26:59.400 回答
1

通过在您不想要的活动之前设置标志来完成从历史记录中删除活动

A->B->C->D

假设 A、B、C 和 D 是 4 个活动,如果要清除 B 和 C 然后设置标志

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

在活动 A 和 B

这是代码位

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
于 2019-12-24T09:14:37.163 回答
1

只需像这样在 startActivity(intent) 之前调用 this.finish() -

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);
于 2017-09-28T09:23:34.267 回答
0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }
于 2020-05-12T05:16:24.553 回答
-7

尝试这个:

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

它是 API 级别 1,请检查链接

于 2013-03-22T11:43:22.637 回答