如何防止回到之前的活动?

Posted

技术标签:

【中文标题】如何防止回到之前的活动?【英文标题】:How to prevent going back to the previous activity? 【发布时间】:2012-01-27 16:49:52 【问题描述】:

当按下手机上的 BACK 按钮时,我想阻止特定活动返回到之前的活动。

具体来说,我有登录和注册屏幕,当成功登录/注册时,它们都会启动一个名为HomeScreen 的新活动。启动 HomeScreen 后,我想阻止用户通过按 BACK 键返回登录或注册屏幕。

我尝试使用Intent.FLAG_ACTIVITY_NO_HISTORY,但由于应用程序集成了 Facebook,当使用“使用 Facebook 登录”时,Facebook 应该返回初始登录屏幕,因此我应该保留这些活动的历史记录。

我想在按下按钮时覆盖 HomeScreen 上的 BACK 按钮的行为并直接完成应用程序

@Override
public void onBackPressed() 
    finish();

但这也行不通。

【问题讨论】:

澄清一下,您试图捕捉除 facebook 之外的所有人的行为? 在某种意义上是的,但实际上我想要的是在成功登录并打开 HomeScreen 之后,用户应该无法通过按 BACK 按钮返回登录屏幕。就像 Twitter 或 Foursquare 一样,一旦我们登录到这些应用程序,在我们注销之前我们看不到登录页面(即使我们在登录后按 BACK)。 【参考方案1】:

我的建议是完成您不希望用户返回的活动。例如,在您的登录活动中,在您拨打startActivity 之后,立即拨打finish()。当用户点击后退按钮时,他们将无法进入登录活动,因为它已被从堆栈中删除。

【讨论】:

如果我希望上一个活动中的线程继续运行怎么办? 那时你不会想采用我的方法。调用 finish() 将终止活动。您能否在您将要进行的活动中启动您想要运行的流程? 注意:如果您在共享过渡期间致电finish,您可能会忘记之前的活动。例如,如果您有HomeActivity -> IntermediateActivity -> FinalActivity,并且在启动FinalActivity 后立即在IntermediateActivity 中调用finish(),您将在短时间内看到HomeActivity @DavidMurdoch 您知道针对该特定情况的任何解决方案吗?【参考方案2】:

以下解决方案在通常的登录/主要活动场景或实施阻止屏幕中非常有用。

要最小化应用程序而不是返回之前的活动,您可以像这样覆盖onBackPressed()

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

moveTaskToBack(boolean nonRoot) 保留您的后台堆栈,只是将您的任务(所有活动)置于后台。 与用户按下主页按钮相同

参数boolean nonRoot - 如果为假,则仅当活动是任务的根时才有效;如果为 true,它将适用于任务中的任何活动。

【讨论】:

非常适合登录屏幕,因为它可以保持历史记录完整。 谢谢,我找了大约三天。因为 Activity 的 android:noHistory="true" 标志不能按预期工作(noHistory 标志在最小化后重新创建活动)并且 finish() 有时对我不起作用,但为什么我仍然不明白。【参考方案3】:

我不确定你到底想要什么,但听起来应该是可能的,而且听起来你已经走在正确的轨道上。

以下是一些可能有帮助的链接:

Disable back button in android

  MyActivity.java =>
    @Override
    public void onBackPressed() 

       return;
    

How can I disable 'go back' to some activity?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>

【讨论】:

我不能使用 noHistory 选项,因为我试图在我的问题中解释的 Facebook 问题以及 cmets 之一。但是带有 BACK 按钮的东西并不是禁用它,而是让它像System.exit(0) 一样退出整个应用程序(我知道这不是最好的做法,但我只是想举个例子)。 谢谢,效果很好。我在这里提出的唯一建议是,无需退货。只需删除 super.onBackPressed(); 并将方法留空。这也很好用【参考方案4】:

您的情况有两种解决方案,活动A启动活动B,但您不想在活动B中回到活动A。

1.从后台堆栈中删除了之前的活动 A。

    Intent intent = new Intent(activityA.this, activityB.class);
    startActivity(intent);
    finish(); // Destroy activity A and not exist in Back stack

2。在活动 B 中禁用返回按钮操作。

有两种方法可以防止返回事件,

1) 推荐方法

@Override
public void onBackPressed() 

2)重写onKeyDown方法

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
    if(keyCode==KeyEvent.KEYCODE_BACK) 
        return false;
    
    return super.onKeyDown(keyCode, event);

希望它有用,但仍取决于您的情况。

【讨论】:

禁用onBackPressed() 用户体验不好吗? 这完全取决于你想要做什么,在应用程序功能中需要这个然后去做。 我完全忘记了使用finish() 的第一种方法,这真是令人惊讶。对nohistory 属性、意图标志、父活动清单标签等进行了不必要的过度考虑!傻,谢谢你的回答!【参考方案5】:

既然已经提出了很多很好的解决方案,我试着给出一个更具描述性的解释。

如何跳过回到上一个活动?

从 Backstack 中移除前一个 Activity。简单

如何从Backstack中移除之前的Activity?

调用finish()方法

正常流程:

所有活动都存储在称为 Backstack 的堆栈中。 当您启动一个新的 Activity(startActivity(...)) 时,新的 Activity 将被推到堆栈顶部,当您按下返回按钮时,该 Activity 将从堆栈中弹出。一个关键点请注意,当按下后退按钮时,会在内部调用 finish(); 方法。这是 onBackPressed() 方法的默认行为。

那么如果你想跳过活动 B?

即A

只需在活动 B 中的 startActvity(...) 之后添加 finish(); 方法

Intent i = new Intent(this, C.class);
startActivity(i);
finish();

【讨论】:

这是部分解决方案,context 没有finish() Activity有finish()方法。【参考方案6】:

finish() 为您提供关闭当前活动而不是整个应用程序的方法。而且你最好不要试图寻找杀死应用程序的方法。一点建议。

你试过Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY的连词吗?记得在Intent开始活动中使用这个标志!

【讨论】:

FLAG_ACTIVITY_NO_HISTORY 阻止我的 LoginScreen 在使用 Login with Facebook 时捕获 Facebook 的回调。因为一旦焦点离开 LoginScreen 就无法恢复(因为没有历史记录)。但是我没有用Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS尝试过,我会检查一下,谢谢! 也感谢finish()方法,我不知道。【参考方案7】:

finish()放在后面

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();

【讨论】:

这基本上是四年前公认的答案。【参考方案8】:

如果您不想返回应用程序上的所有活动,可以使用

android:launchMode="singleTask"

在此处了解更多信息:http://developer.android.com/guide/topics/manifest/activity-element.html

【讨论】:

【参考方案9】:

paulsm4 的答案是正确的。如果在onBackPressed() 中您只是返回,它将禁用返回按钮。但是,考虑到您的用例,我认为更好的方法是翻转活动逻辑,即将您的家庭活动作为主要活动,检查用户是否在那里登录,如果没有,则开始登录活动。原因是,如果您在主活动中覆盖后退按钮,大多数用户会在按下后退时感到困惑,而您的应用程序什么也不做。

【讨论】:

【参考方案10】:

此方法运行良好

Intent intent = new Intent(Profile.this, MainActivity.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

【讨论】:

【参考方案11】:

只需重写 onKeyDown 方法并检查是否按下了返回按钮。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 

    if (keyCode == KeyEvent.KEYCODE_BACK) 
    
        //Back buttons was pressed, do whatever logic you want
    

    return false;

【讨论】:

【参考方案12】:
@Override
public void onBackPressed() 

当您创建 onBackPressed() 时,只需删除 super.onBackPressed(); 就可以了

【讨论】:

【参考方案13】:

finish();

紧接着 活动开始 停止活动以防止任何方式回到它。 然后添加

onCreate()
    getActionBar().setDisplayHomeAsUpEnabled(false);
    ...

到您正在开始的活动。

【讨论】:

以上是关于如何防止回到之前的活动?的主要内容,如果未能解决你的问题,请参考以下文章

从通知启动时防止重新创建活动活动

如何返回之前的活动?

尽可能长时间地防止活动被破坏

防止键盘在活动开始时显示

如何清除 Android Stack 的活动?

防止从通知点击创建新活动