Android:从返回栈中删除所有以前的活动
Android:从返回栈中删除所有以前的活动
当我点击我的个人资料活动中的注销按钮时,我希望将用户带到登录页面,并需要使用新的凭据。\n因此,我使用了这段代码:\n在注销按钮的onButtonClick中:\nIntent intent = new Intent(ProfileActivity.this, LoginActivity.class);\nintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); \nintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\nstartActivity(intent);\n但问题是,当我在登录活动中点击设备的返回按钮时,它会将我带回到个人资料活动。我原本期望在登录活动上按下设备返回按钮时应用程序应该关闭。\n我做错了什么?\n我还在清单中为我的登录活动添加了android:launchMode=\"singleTop\"。\n谢谢你。
原因:问题的出现是因为在Android中,当我们通过意图(intent)启动一个活动(activity)并结束当前活动时,如果我们想要移除所有在当前活动之前的活动,我们需要使用finishAffinity()方法。然而,在API 16之前,我们需要使用ActivityCompat.finishAffinity()方法来实现相同的功能。
解决方法:为了解决这个问题,我们可以使用ActivityCompat.finishAffinity()方法来代替finish()方法。这个方法将会结束所有在当前活动之前的活动,并且对我来说运行良好。
代码示例:
finishAffinity(); // API 16及以上 ActivityCompat.finishAffinity(this); // API 15及以下
通过使用ActivityCompat.finishAffinity()方法,我们可以移除所有在当前活动之前的活动,从而实现清空活动栈的效果。这个方法在API 16及以上版本中可以直接使用,而在API 15及以下版本中需要使用ActivityCompat.finishAffinity()方法来替代。
在使用注销按钮时,有一种解决方案可以清除应用程序的所有活动。每次启动一个活动时,使用以下方式启动:
Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class); startActivityForResult(myIntent, 0);
当您想关闭整个应用程序时,执行以下操作:
setResult(RESULT_CLOSE_ALL); finish();
RESULT_CLOSE_ALL是一个带有唯一整数的最终全局变量,用于表示您要关闭所有活动。然后,定义每个活动的onActivityResult(...)回调,以便当一个活动返回RESULT_CLOSE_ALL值时,它也调用finish():
protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(resultCode) { case RESULT_CLOSE_ALL: setResult(RESULT_CLOSE_ALL); finish(); } super.onActivityResult(requestCode, resultCode, data); }
这将导致级联效应,关闭所有活动。
这是一种hack的方法,使用了startActivityForResult,但它的设计并不是为了这样使用。
也许更好的方法是使用广播接收器,如下所示:
还可以参考以下线程中的其他方法:
Finish all previous activities
如果您的历史记录中有大约30个活动,是否可行?
应该是可以的。但是,如果您的历史记录中有30个活动,您可能需要考虑更改设计。30个活动似乎有点太多了,Android可能会自己终止它们。
这似乎是一种不好的方法。's answer question'似乎是合法的。30可能只是表示'高'数量的一个数字。这个答案看起来更好:stackoverflow.com/a/3008684/243709
这个答案很棒。您还可以使用EventBus库将事件发送到后台堆栈中的活动。github.com/greenrobot/EventBus
最好使用简单的'Intent.FLAG_ACTIVITY_CLEAR_TOP'标志和意图。
在Android中,有时候我们希望在启动一个新的Activity时,清除掉之前所有的Activity,使得新的Activity成为任务栈的根Activity。这个问题的解决方法如下:
Java代码:
Intent i = new Intent(OldActivity.this, NewActivity.class); // 设置新的任务栈并清除标志 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i);
Kotlin代码:
val i = Intent(this, NewActivity::class.java)
// 设置新的任务栈并清除标志
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)
需要注意的是,这个方法需要API level >= 11才能使用。
还有一种解决方法是使用`FLAG_ACTIVITY_CLEAR_TASK`标志,这是官方的推荐方法,不需要改变应用中的所有Activity。但是需要注意,这种方法对于通知中的PendingIntent可能不起作用。
另外,某些情况下在API level > 21的情况下,执行视图的速度可能会变慢,而在API level < 21的情况下会更加流畅。某些情况下在有多个任务栈(Activity stack)的情况下,这种方法可能不起作用,例如有四个Activity A、B、C和D,存在两个任务栈A->B->C(后台)和D->A->B(前台),如果从当前任务栈(D->A->B)中通过建议的方法启动Activity A,会清除当前任务栈并打开Activity A,当按下返回键时会关闭应用程序,但如果按下最近使用的应用程序按钮,可以看到应用程序的两个任务栈。