前言
Intent如果设置FLAG_ACTIVITY_CLEAR_TOP,并且要启动的activity已经在当前的任务中,那么在该activity之上的activity都会关闭,并且intent会传递给老的activity(现在在栈顶)
例如,假设一个任务包含四个activity:A,B,C,D,假设D中启动B并且带有这个标志,则 C和D都会结束,并且B会收到intent,现在的栈变成了A,B。
官方解释:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
在上面的例子中,当前运行的B要么在他的onNewIntent方法中接受这个Intent,或者结束掉已经存在的实例并且重启一个,这依赖于B的启动模式,如果是”multiple(即standard)”模式,那么就会结束掉当前Activity实例并重启一个,其他启动模式下将会直接调用他的onNewIntent。
使用场景
问题:多activity中退出整个程序,例如从A->B->C->D,这时我需要从D直接退出程序。
finish()和system(0)都只能退出单个activity。杀进程等的等方式都不行。
解决方式:
我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在D窗口打开A窗口时在Intent中直接加入标志Intent.FLAG_ACTIVITY_CLEAR_TOP,再次开启A时将会清除该进程空间的所有Activity。
使用示例
在D中使用下面的代码:
在A中加入代码:
A的Manifest.xml配置成android:launchMode=”singleTop”
原理总结
一般A是程序的入口点,从D起一个A的activity,加入标识Intent.FLAG_ACTIVITY_CLEAR_TOP这个过程中会把栈中B,C,都清理掉。因为A是android:launchMode=”singleTop”
不会调用oncreate(),而是响应onNewIntent()这时候判断Intent.FLAG_ACTIVITY_CLEAR_TOP,然后把A finish()掉。
栈中A,B,C,D全部被清理。所以整个程序退出了。
补充说明
1.可以把A设置成不可见的Acitivity(方法见下面),然后在它的onCreate方法里跳转到“真正”的载入界面就可以实现在D中点退出程序按钮时看上去立即退出程序的效果。
2.A必须是程序启动的第一个Activity才能起到这种立即退出的效果,因为Intent.FLAG_ACTIVITY_CLEAR_TOP只会把目标Activity的“上面”的Activity清理掉,而如果目标Activity的“下面”还有Activity(换句话说,目标Activity不在栈底),则finish后只会到他下面的那个Activity,而不是立即退出的效果了。
3.不可见Activity
在项目的AndroidManifest.xml文件中相应的Activity标签中添加这样一行:
这样一来,当这个Activity启动的时候,就不会显示出界面了。