从历史堆栈中删除活动

时间:2009-12-14 04:15:45

标签: android android-activity activity-lifecycle

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

  1. ActivitySplashScreen(欢迎使用游戏,注册帐户?)
  2. ActivitySplashScreenSignUp(很棒,填写此信息)
  3. ActivityGameMain(主游戏画面)
  4. 所以当用户点击每个屏幕上的按钮时,活动会按照这个顺序相互启动。

    当用户从活动#2转到#3时,是否可以完全从历史堆栈中删除#1和#2?我喜欢这样,如果用户位于#3,然后点击后退按钮,他们就会转到主屏幕,而不是回到启动画面。

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

    由于

16 个答案:

答案 0 :(得分:605)

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

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

答案 1 :(得分:134)

您可以使用转发功能在启动下一个活动时从活动堆栈中删除以前的活动。 There's an example of this in the APIDemos,但基本上您所做的只是在致电finish()后立即致电startActivity()

答案 2 :(得分:49)

是的,请查看Intent.FLAG_ACTIVITY_NO_HISTORY

答案 3 :(得分:23)

这可能不是理想的做法。如果某人有更好的方法,我将期待实施它。以下是 I 使用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)线程。

答案 4 :(得分:21)

在API 11之前运行的一种方法是首先启动ActivityGameMain,然后在该活动的onCreate中启动您的ActivitySplashScreen活动。 ActivityGameMain将不会出现,因为您很快就会调用startActivity。

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

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

答案 5 :(得分:17)

我用这种方式。

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

答案 6 :(得分:8)

我知道我迟到了(问题问题已经过去了两年)但是我通过拦截后退按钮完成了这个。我只是查看计数,而不是检查特定活动,如果它小于3,它只是将应用程序发送到后面(暂停应用程序并将用户返回到启动前运行的任何内容)。我检查的不到三个,因为我只有一个介绍屏幕。此外,我检查计数,因为我的应用程序允许用户通过菜单导航回主屏幕,因此这允许他们通过其他屏幕备份,如果除了堆栈上的介绍屏幕之外的其他活动,则正常。

//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();
    }
}

答案 7 :(得分:6)

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

答案 8 :(得分:6)

在清单中,您可以添加:

android:noHistory="true"

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

您也可以致电

finish()

在调用startActivity(..)后立即

答案 9 :(得分:3)

for API&gt; = 15到API 23 其他解决方案不适用于我的情况。最后我得到了这个。

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

答案 10 :(得分:3)

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

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。这是推荐的解决方案,应该被接受。

答案 11 :(得分:3)

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

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

来自Android文档:

  

公共静态最终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。

答案 12 :(得分:1)

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

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);

答案 13 :(得分:0)

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

A-> B-> C-> D

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

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

答案 14 :(得分:0)

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

答案 15 :(得分:-7)

试试这个:

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

是API级别1,请检查link