【问题标题】:Android: Clear the back stackAndroid:清除后台堆栈
【发布时间】:2011-08-13 06:19:48
【问题描述】:

在 Android 中,我有一些活动,比如 A、B、C。

在A中,我用这段代码打开B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

在B中,我用这段代码打开C:

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

当用户点击 C 中的按钮时,我想返回 A 并清除后台堆栈(关闭 B 和 C)。所以当用户使用后退按钮 B 和 C 时不会出现,我一直在尝试以下操作:

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

但是如果我在返回活动 A 时使用返回按钮,B 和 C 仍然会出现。我该如何避免这种情况?

【问题讨论】:

    标签: android android-intent android-activity stack


    【解决方案1】:

    尝试按照FLAG_ACTIVITY_CLEAR_TOP 的文档中的说明添加FLAG_ACTIVITY_NEW_TASK

    此启动模式也可用于 配合效果不错 FLAG_ACTIVITY_NEW_TASK:如果用于 启动任务的根活动,它 将带来任何当前正在运行的 该任务的实例 前景,然后将其清除到其 根状态。这个特别好用 例如,当启动一个 通知中的活动 经理。

    因此,您启动 A 的代码将是:

    Intent intent = new Intent(this, A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(intent);
    CurrentActivity.this.finish(); // if the activity running has it's own context
    
    
    // view.getContext().finish() for fragments etc.
    

    【讨论】:

    • 谢谢,但我已经试过了。仍然当我再次显示 C 后点击返回按钮时。我会错过什么?
    • intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
    • 对我不起作用,但是在源活动上调用 finish() 可以实现我需要实现的目标
    • 我遇到了同样的问题,这不起作用。为我解决的问题是在开始新活动后调用 finish()
    • 我还添加了一个更清晰的 Intent intent = new Intent(SingUpActivity.this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);开始活动(意图);完成();
    【解决方案2】:
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(intent);
    

    【讨论】:

    • 考虑到CLEAR_TOP 标志 - 此组合是唯一完全清除整个堆栈并使新活动成为应用程序中唯一的组合。谢谢!
    • 这与接受的答案有什么区别?
    • 谢谢,与接受的答案不同的是,有了这个标志,我们不需要调用 activity.finish
    • FLAG_ACTIVITY_CLEAR_TASK 与 NEW_TASK 完美配合
    • 这应该是公认的答案。非常感谢。
    【解决方案3】:

    如何为相关活动添加清单文件:

    android:noHistory="true"
    

    对 B 和 C 的活动定义?它们不会被添加到 backstack 中。不确定这是否是您想要的。

    【讨论】:

    • 使用此功能时要非常小心 - 如果您使用 FB 登录或任何类似功能
    • @Skynet 为什么?这样做有什么问题?
    • 当您将控制权传递给 FB 以从 nohistory 为 true 的页面登录时,FB 应用程序现在在用户登录后无法登陆,在我的情况下,它返回到手机主屏幕我差点丢了工作!
    • 这不允许将活动添加到后台堆栈中......这不是正确的解决方案。
    • 正是我在寻找
    【解决方案4】:

    这困扰了我很长时间。最后我通过这样做解决了这个问题:

    在片段中,使用:

    Intent intent = new Intent(view.getContext(), A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(intent);
    

    在Activity中,使用(与fragment相比,多加一个intent flagIntent.FLAG_ACTIVITY_CLEAR_TASK):

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

    【讨论】:

    • 如果你使用的是androidannotations,你必须添加:Intent.FLAG_ACTIVITY_CLEAR_TASK
    • 活动解决方案对我来说效果很好。虽然我认为使用 API 16,Daniel Schuler 的解决方案更容易。
    • 谢谢 yosafatade,这正是我所缺少的!
    【解决方案5】:
    1. android:launchMode="singleTop" 添加到活动 A 清单中的活动元素
    2. 然后使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 启动 Activity A 时

    这意味着当Activity A启动时,它上面的所有任务都会被清除,这样A就处于顶部。以 A 为根创建了一个新的后退堆栈,使用 singleTop 可确保您只启动 A 一次(因为由于 ..._CLEAR_TOP,A 现在位于顶部)。

    【讨论】:

    • 是的。这就是我现在正在使用的,但它并没有这样做。当我点击后退按钮时,仍然会显示 C。
    • 奇怪,我在一个项目中使用了它,它工作正常......按回将我带到主屏幕。也许还有其他事情发生。你能发布你的清单吗?
    • 我重新启动了模拟器,现在它似乎像你说的那样工作了。非常感谢您的帮助!
    • singleTop 应该和清栈无关。
    【解决方案6】:

    从 API 16 (Jelly Bean) 开始,您只需调用 finishAffinity()

    现在您还可以使用兼容性库调用ActivityCompat.finishAffinity(Activity activity)

    确保将清单中的 taskAffinity 设置为该组活动唯一的包名称。

    查看更多信息:
    http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29

    【讨论】:

    • 如果您已经使用 API 16,这是非常有用且简单的解决方案。为我工作!
    • 提醒:这仅适用于共享相同 taskAffinity 名称的活动
    • 仅当您在历史记录中只有一项活动时才有效。
    【解决方案7】:

    尝试使用

    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    

    而不是

    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    

    【讨论】:

    • 这行得通。我的假设是使用 setFlags 将替换所有默认设置标志,但事实并非如此
    【解决方案8】:

    如果您的应用程序具有最低 sdk 版本 16,那么您可以使用 finishAffinity()

    在当前任务中完成此活动以及紧接其下方的所有具有相同亲和力的活动。

    这对我有用 在 Top Payment 屏幕中,移除所有 back-stack activits,

     @Override
    public void onBackPressed() {
             finishAffinity();
            startActivity(new Intent(PaymentDoneActivity.this,Home.class));
        } 
    

    http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29

    【讨论】:

      【解决方案9】:

      根据Wakka in Removing an activity from the history stack...


      android:noHistory="true" 属性添加到<activity> 中的AndroidManifest.xml,如下所示:

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

      【讨论】:

        【解决方案10】:

        使用finishAffinity();在任务 C 中启动任务 A 以清除 backstack 活动。

        【讨论】:

        • 只有这个答案对我有用。 Intent.FLAG_ACTIVITY_CLEAR_TOP 和 Intent.FLAG_ACTIVITY_NEW_TASK 不是必需的
        【解决方案11】:

        为了将来的研究,试试这个代码。

        Intent intent = new Intent(context, LoginActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
        

        【讨论】:

        • 这些标志终于为我工作了。我所做的是我使用这些标志和一个布尔额外的 EXIT=true 启动了与我相同的活动。在 onCreate() 中,我检查了 EXIT 的启动参数,如果设置为 true,则调用 finish()。仅仅关闭你自己的应用程序就很麻烦。
        【解决方案12】:
        Use finishAffinity() to clear all backstack with existing one.
        
        Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 
        
            - Activity B will be finished / removing from stack.
            - Activity A will be finished / removing from stack.
            - Activity C will finished / removing from stack.
        

        【讨论】:

          【解决方案13】:

          使用此代码启动新的 Activity 并关闭或销毁所有其他 Activity 堆栈或返回堆栈。

          Intent intent = new Intent(this, MainActivity.class);
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
          startActivity(intent);
          

          【讨论】:

            【解决方案14】:

            我找到了一个有趣的解决方案,可能会有所帮助。我在 onBackPressed() 方法中做到了这一点。

            finishAffinity();
            finish();
            

            FinishAffinity 删除现有活动与其堆栈的连接。然后完成可以帮助您退出该活动。最终会退出应用程序。

            【讨论】:

              【解决方案15】:

              在 kotlin 中几乎和 java 一样。只有 | 符号被 文本替换。 所以,它是这样写的-

              intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
              

              【讨论】:

                【解决方案16】:

                我发现这里的答案有点误导,因为原始问题中的代码似乎对我来说很好用?

                由于 A 是根 Activity,仅使用 FLAG_ACTIVITY_CLEAR_TOP 从 B 或 C 启动它确实会从后台堆栈中删除 B 和 C。

                【讨论】:

                  【解决方案17】:

                  在我看来,您需要使用 startActivityForResult()Activity B 开始 Activity C。当您单击Activity C 中的按钮时,调用setResult(RESULT_OK)finish(),这样Activity C 就结束了。在Activity B 中,您可以通过同时调用finish() 来让onActivityResult() 响应,然后您将被带回Activity A

                  【讨论】:

                  • 是的,但是如果A和C之间有42个活动,这将是相当乏味的。 FLAG_ACTIVITY_CLEAR_TOP 标志应该直接执行 OP 想要的操作。
                  • 这将不是实现 OP 想要的最佳方式,正如@Guillaume 所说,它需要在根目录和堆栈顶部之间的所有活动中使用代码。跨度>
                  • 正式注明。这些显然是我需要了解的标志。
                  【解决方案18】:

                  高级、可重用的 Kotlin:

                  您可以直接使用 setter 方法设置标志。在 Kotlin 中,or 是 Java 按位的 replacement|

                  intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
                  

                  如果多次使用,创建一个 Intent 扩展函数

                  fun Intent.clearStack() {
                      flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                  }
                  

                  然后您可以在启动意图之前直接调用此函数

                  intent.clearStack()
                  

                  如果您需要在其他情况下添加附加标志的选项,请在扩展函数中添加一个可选参数。

                  fun Intent.clearStack(additionalFlags: Int = 0) {
                      flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                  }
                  

                  【讨论】:

                    【解决方案19】:

                    我尝试了所有解决方案,但没有一个适合我。 我的解决方案是:

                    通过在 Android 清单中使用 [android:launchMode="singleTop"]Activity A 声明为 SingleTop

                    现在在从任何地方启动A 时添加以下标志。它将清除堆栈。

                    Intent in = new Intent(mContext, A.class);
                    in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
                    startActivity(in);
                    finish();
                    

                    【讨论】:

                      【解决方案20】:

                      Intent.FLAG_ACTIVITY_CLEAR_TOP 在这种情况下不起作用。请使用(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

                      更多详情请查看this 文档。

                      【讨论】:

                        【解决方案21】:

                        Kotlin 示例:

                              val intent = Intent(this@LoginActivity, MainActivity::class.java)
                              intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
                              startActivity(intent)
                              finish()
                        

                        【讨论】:

                          【解决方案22】:

                          logout.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                          【讨论】:

                            【解决方案23】:
                             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            

                            【讨论】:

                              【解决方案24】:

                              对我来说添加Intent.FLAG_ACTIVITY_CLEAR_TASK 解决了问题

                              Intent i = new Intent(SettingsActivity.this, StartPage.class);
                                              i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                                              startActivity(i);
                              finish();
                              

                              【讨论】:

                                【解决方案25】:

                                您可以使用此示例从Activity C 调用您的Activity A

                                Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);

                                【讨论】:

                                  【解决方案26】:

                                  除了FLAG_ACTIVITY_CLEAR_TOP,您还可以尝试添加Intent.FLAG_ACTIVITY_SINGLE_TOP

                                  intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                                  【讨论】:

                                  • 那只会影响栈顶的activity,而不是它的根。
                                  【解决方案27】:

                                  给定的代码可以正常工作。我已经在应用程序生命周期示例中进行了尝试。

                                  在使用标志 FLAG_ACTIVITY_CLEAR_TOP 启动活动 A 后,我在后退堆栈中没有 B 和 C

                                  【讨论】:

                                    【解决方案28】:

                                    我在开始新意图后打电话给activity_name.this.finish(),它对我有用。

                                    I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"
                                    

                                    但这对我不起作用...我不建议使用此解决方案,但如果设置标志对您不起作用,那么您可以尝试这个..但我仍然建议不要使用它

                                    【讨论】:

                                      【解决方案29】:

                                      在 Intent 中添加 NO History Flag。

                                      在活动B中,启动活动C如下>>>>>>

                                      Intent intent = new Intent(this, C.class);
                                      intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
                                      startActivity(intent);
                                      finish();
                                      

                                      【讨论】:

                                        【解决方案30】:

                                        在清单中

                                        android:launchMode="singleTask"
                                        

                                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                        startActivity(intent);
                                        

                                        【讨论】:

                                          猜你喜欢
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 2011-10-27
                                          • 1970-01-01
                                          相关资源
                                          最近更新 更多