关于android:从历史堆栈中删除活动

Removing an activity from the history stack

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

  • ActivitySplashScreen(欢迎使用游戏,注册帐户?)
  • ActivitySplashScreenSignup(很好,请填写此信息)
  • 活动GameMain(主游戏屏幕)
  • 因此,当用户单击每个屏幕上的按钮时,这些活动就按照相同的顺序彼此启动。

    当用户从活动2转到活动3时,是否可以完全清除历史堆栈中的1和2?我希望这样,如果用户在3,点击后退按钮,他们只会进入主屏幕,而不是回到初始屏幕。

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

    谢谢


    您可以通过在您的AndroidManifest.xml文件中的相关条目中将android:noHistory属性设置为"true"来实现这一点。例如:

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


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


    是的,看看意图。标记"活动"的"否"历史。


    这可能不是理想的方法。如果有人有更好的方法,我将期待实现它。以下是我如何使用11版前的SDK完成这个特定任务。

    在每节课上,如果你想在空闲时间离开,你需要这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        ... 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();
        }
    }

    然后,需要从堆栈中设置pop链的人需要在您想启动它时调用它:

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

    那么活动就不在堆栈上了!记住,伙计们,您可以启动一个活动,然后在它后面开始清理,执行不会遵循单个(UI)线程。


    API 11之前的一种工作方式是先启动ActivityGameMain,然后在该活动的onCreate中启动ActivitySplashScreen活动。当您调用StartActivity时,ActivityGameMain不会出现,因为启动太快。

    然后,您可以在启动ActivityGameMain时清除堆栈,方法是将这些标志设置在意图上:

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

    您还必须将此添加到ActivitySplashScreen:

    1
    2
    3
    4
    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
    }

    所以,继续进行这种活动不会回到你的ActivityGameMain

    我想你不想让闪屏回到原来的屏幕上,为了达到这个目的,我建议在你的AndroidManifest.xml中设置为noHistory。然后把goBackPressed代码放在ActivitySplashScreenSignUp类中。

    不过,我找到了一些方法来打破这种局面。当显示ActivitySplashScreenSignUp且后台历史记录未重置时,从通知中启动另一个应用程序。

    唯一的解决方法是API 11:

    1
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

    我用这种方式。

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //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();
        }
    }

    在清单中,您可以添加:

    1
    2
    3
    4
    5
    android:noHistory="true"

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

    你也可以打电话

    1
    finish()

    在调用StartActivity(..)后立即


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


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

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

    来自Android文档:

    public static final int FLAG_ACTIVITY_CLEAR_TASK
    Added in API level 11

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

    activity to be cleared before the activity is started. That is, the
    activity becomes the new root of an otherwise empty task, and any old
    activities are finished. This can only be used in conjunction with
    FLAG_ACTIVITY_NEW_TASK.


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

    SplashActivity -> AuthActivity -> DashActivity

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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。这是建议的解决方案,应予以接受。


    对于API>=15至API 23其他解决方案在我的情况下不起作用。终于有了这个。

    1
    2
    3
    4
     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);


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

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


    试试这个:

    intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

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