首先要知道的概念是 栈 这个一般都知道的了,然后,Android中activity的装载方式就是使用的栈的方式的。
相信大家经常会遇到这样的一种情况
在某个activity中点个按钮,然后跳的另一个activity,但是要finish掉之前的所有activity
(你说你没遇到? 反正我是遇到了)
最经典的例子就是,那个坑爹的退出登录一般是在一个叫 SetActivity 里面,可是这个SetActivity 是 MainActivity 跳过来的,点击退出登录,可以干掉的是 SetActivity 然后跳到 LoginActivity,但是 MainActivity 还在,不符合跳转逻辑啊。
文字描述有点累赘,换个抽象的
定义
S:SetActivity
M:MainActivity
L:LoginActivity
开始是
M,S
退出登录是
M,L
再登录是
M,L,M
多了个M
这还是只多了一个的情况,挺好解决的
问题是我遇到的是多了N多个activity在中间,分分钟跳转就乱了
解决的办法有3种
第一种:用个list装起来全部的activity,每次打开一个activity的时候传个context进去,finish的时候移除就好,可以用BaseActivity封装好也不是特别麻烦,要干掉全部的时候,一个循环就干掉了,详细的代码百度下就好
第二种:用广播,就是之前写的RxBus或者eventBus,或者自己写,要退出了发送个退出的广播,要关掉的activity注册个监听接收广播后finish掉就好。一开始我也是这么干的,后来中间多了太多activity了,代码差点乱套。
第三种:这种其实才是最正宗的
辣就是设置启动方式
其实一直都知道activity的启动方式有4种
standard 这个是默认的,正常都用这种
singleInstance这个是坑爹的,一般不用,也最好不要乱用,它会新建多一个栈
手机查看所有启动应用的窗口再一键清除的嘛,具体表现就是用了以后,这里会有2个窗口。反正不用就是了
singleTop这个很不错
比如默认就是
A-B-C-D-D-D-D
用了这个后就是
A-B-C-D
D这个activity再打开自己,就不会new一个了,就会一直用自己这个
但是··············
不会重新调用
onCreate
而是调用
onNewIntent
这个方法了,所有新的数据啊什么的要放这里面
比如我传值过来
@Override
protected void onNewIntent(Intent intent) {
//data= getIntent().getStringExtra("数据"); //坑点
String data = intent.getStringExtra("数据"); //注意点
super.onNewIntent(intent);
}
getIntent()是之前的intent数据
新打开的intent的数据是(Intent intent)这里面intent的数据
好,最后一种,也是题目能解决结束多个activity的这种
好东西总要压轴嘛
singleTask就是你了
它的功能就是
如果要启动的Activity不在,就创建新的然后放到栈顶。
如果要启动的Activity已经在栈顶,就跟singleTop模式一样。
如果要启动的Activity已经在于栈中,就会干掉这个Activty上面的所有其他Activty。
举个栗子:
1.A-B-C-D------E
A-B-C-D-E
2.A-B-C-D------D
A-B-C-D------D
3.A-B-C-D------B
就变成
A-B
就是这么炫酷
好回到上面的那个难题
开始是
M,S
退出登录是
M,L
再登录用了这个以后就是
M,L-----M就只剩下了M
虽然退出登录并不能结束全部activity然后跳到LoginActivity,
但是这样的逻辑才是最正确的,再登录以后就一切正常了。
讲了这么多怎么样设置才是重点
其实出乎意料的简单
就是在manifest里面
<activity
android:name=".******.****.*******"
android:launchMode="singleTop" //这就行了
android:screenOrientation="portrait" //这个是竖屏显示,表示不能横屏
android:theme="@style/AppTheme"/>
当然也可以在intent跳转的时候给intent加个Flag,你喜欢就好,反正我不想那样加
clearTaskOnLaunch
话说这个也是管理activity栈的很有意思,虽然用不到,有兴趣可以去找找