Android从后台堆栈中删除活动

Posted

技术标签:

【中文标题】Android从后台堆栈中删除活动【英文标题】:Android remove Activity from back stack 【发布时间】:2012-12-16 05:45:25 【问题描述】:

好的,所以我有点不知道如何处理这个问题。所以我有 MainActivity,可以从那里启动一个 Activity 到 DegreePlanActivity,然后从那里启动另一个 Activity 到 EditDegreePlan。我在 androidManifest 中将 EditDegreePlan 设置为 noHistory。问题是在他们保存 EditDegreePlan 后,它会向 DegreePlan 启动一个活动。因此,如果用户按 Back,他们必须按两次才能再次进入 MainActivity。我想摆脱它,所以他们只需要按一次。不过,我对如何做到这一点感到困惑。

如果我将 DegreePlanActivity 设置为 noHistory,那么在 EditDegreePlan 中他们无法按 Back to it。

我已经尝试覆盖 onBackPressed 方法并启动 MainActivity 的意图。那么问题是他们必须多次按 Back 才能退出应用程序。

我该怎么办?

【问题讨论】:

在startActivity方法之后写finish() 【参考方案1】:

FLAG_ACTIVITY_CLEAR_TOP清空你的Activity栈,你可以使用下面的代码:

Intent intent = new Intent(this, Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

请记住,此标志仅清除中间活动,例如,如果您的 Back Stack 中有 A、B、C,则使用此标志从 C 活动转到 D,这 不会 清除 @987654324 @ 并且堆栈将是 A,B,C,D 但是如果您使用此标志从 Activity D 转到 Activity A ,则 B,C,D 活动将从堆栈中弹出,并且您将只有 A 在 Back Stack 。

【讨论】:

谢谢!那工作得很好。我什至可以从 AndroidManifest 中删除 noHistory。只需将那一行代码添加到 EditDegreePlanActivity 的保存方法即可解决所有问题。 如何使用 taskAffinity = ""; ? 哇,这是一个很棒的功能。我不敢相信它有效并且完全符合我的需求。我有一个扫描条形码的后台异步服务。在特定的条形码上,它会启动一些活动。在某些情况下,我需要从堆栈中删除一些已启动的活动。这简直太棒了! 很好的解释!【参考方案2】:

看来,如果您根本不指定任何标志,您将获得所需的行为。后退按钮只会做正确的事情。要从您的代码中关闭活动,请使用finish() 方法,它与用户按下后退按钮的效果相同。所以当你完成EditDegreePlan后你会自动到达DegreePlan,也不需要打电话给任何Intents

【讨论】:

不,finish() 有时做不到(startActivity+finish),Activity 还能多活 10 秒【参考方案3】:

这是您的流程:

MainActivity --> DegreePlanActivty --> EditDegreePlan--> DegreePlan --> MainActivty

在“DegreePlan”中覆盖这些方法

public void onBackPressed() 
   super.onBackPressed();
   Intent goToMainActivity = new Intent(getApplicationContext(), MainActivity.class);
   goToMainActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // Will clear out your activity history stack till now
   startActivity(goToMainActivity);

【讨论】:

【参考方案4】:

我建议您在启动 EditDegreePlan-Activity 时使用startActivityForResult(),而不是简单的startActivity(),如Android tutorials 中所述。

然后在 EditDegreePlan-Activity 中调用

setResult(RESULT_OK);
finish();

如果您不希望 EditDegreePlan-Activity 提供任何数据,那么您不一定要实现 onActivityResult

【讨论】:

不可思议的想法!我的用例:一个简单的登录活动(可能导致注册活动,与用户流程无缝连接),完成登录后,打开一个功能活动。如果用户回击,它应该显示我的第一个活动(触发登录的那个)。解决方案:现在使用startActivityForResult 调用登录和注册活动。当它们完成后,它们就出栈了。谢谢!【参考方案5】:

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

【讨论】:

太棒了!谢谢最新的东西。 非常感谢,但 IntentCompat.FLAG_ACTIVITY_CLEAR_TASK 已弃用,请改用 Intent.FLAG_ACTIVITY_CLEAR_TASK【参考方案6】:

使用它来清除堆栈:

 menuIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TOP);

【讨论】:

【参考方案7】:

您可以在开始新活动之前调用完成。这将从堆栈中删除当前活动,因此当您从下一个活动按返回按钮时,将不会从堆栈历史记录中调用第一个活动。

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

【讨论】:

无论在startActivity()之前还是之后调用,都不会有第一个activity【参考方案8】:

你可以如下添加flags并启动Activity,试试下面的代码

Intent i = new Intent(activity, Payment.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(i);

【讨论】:

【参考方案9】:

要从清单内的后台堆栈中删除活动,请将android:noHistory="true" 添加到清单文件内的活动中。

请参阅下面的示例。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.activity"
      android:versionCode="1"
      android:versionName="1.0">
 <application android:name="MyApp" android:label="My Application">
    <activity android:name=".LoginActivity" 
      android:noHistory="true"> //add this line to your activity inside manifest
     <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
   </activity>
 </application>
</manifest>

【讨论】:

对于闪屏特别有用——配置总是比代码好 即使应用程序进入后台,Activity 也会被销毁【参考方案10】:
Intent intent = new Intent(getContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 

startActivity(intent);

【讨论】:

【参考方案11】:
This code should help you out: It is in Kotlin
private fun verifyIfUserIsLoggedIn()
        val uid = FirebaseAuth.getInstance().uid
        if(uid== null)
            val intent = Intent(this, MainActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        
    

【讨论】:

以上是关于Android从后台堆栈中删除活动的主要内容,如果未能解决你的问题,请参考以下文章

当一个活动直接从一个通知启动时,你如何构建一个 Android 后台堆栈?

Android从后台堆栈中删除事务

Android:OutOfMemory 错误和后台堆栈

Android:如何在按下按钮时关闭一个活动并在按下另一个按钮时关闭整个后台堆栈? [复制]

Android GCM 通知后台堆栈

Android:从历史堆栈中清除旧的活动实例