首先说说,准备写这个的初衷。其实就是自己在工作了一段时间后,再回顾一些基础知识的同时,写这个系列。顾名思义,就是写出来的东西,让小白也能看懂。记得,看过一位大牛在博客里面写过这样一句话:如果,你看不懂某个博客,请不要怀疑自己的智商,那肯定是博主写得不够好。同时,我国伟大诗人,诗仙李白,写的诗词。就是让身为现代人的我们,都能很容易看懂。所以,我也打算效仿这二位神人,写一些对小白比较友好的技术文章,当然,如果有不对或者不清晰的放,也希望大家指正。
为什么第一篇写Activity任务栈和启动模式,因为,像什么textview之类的控件,xml等等,这些,我实在没什么可写的,网络上,随便找,一大堆。我就想写点,曾经让自己犯错,或者疑惑的东西。算是为和曾经的我一样小白的同学,解解惑吧。
首先说说这个“任务栈”,当然有些公司招聘上写的是activity堆栈,其实是一个意思。当然,堆栈和任务栈绝对不是一个意思。关于堆栈的东西,个人觉得那算是java的东西了,这一篇就不讲了,以后有机会会讲到。
那么什么是任务栈,我们把这个东西分解一下,分解为“任务”和“栈”。任务,这个怎么理解呢?嗯,换一种说法,工作,职责,要做的事情。相信这样应该知道了吧。那么什么是栈呢?如果,你有java基础,那么,你可以跳过这一部分。如果没有,没关系,我来解释。栈,男生可以理解为弹夹,因为我们小时候都玩过玩具枪吧,把子弹一颗颗塞进弹夹,而打枪的时候,子弹,再从最上面一颗颗往外发射。女生可以理解衣柜里面衣服,你是叠好之后一件一件往里面放,你要拿衣服出来只能,从最上面开始往外拿(默认情况下)。ok,我这样类比之后,应该就好理解了吧。
总结一下,activity任务栈,是什么?就是一个管理activity的先进后出(栈的特点)的东西。管理activity就是这个任务栈的任务,而存放activity的空间,就是这个栈。下面,再附上一张图,更加直观:
上图,是activity进栈,而出栈,就刚好相反了。这就是常说的,“先进后出”。
而,在官方和很多网上的资料都会提到,压栈,弹栈,其实也好理解,压,通常是往下,弹,通常往上。再结合上面的图,不就真好对应,“放/进”和“取/出”吗。
ok,我应该已经把这个任务栈是什么说的比较清楚了吧,那么最后再总结一下:activity任务栈,是一个有序,且“先进后出”,用于管理,存放activity的集合。
好了,关于activity任务栈的东西,就这样,记住我最后总结的那句话,和上面那张图,就可以了。
补充一点:activity的显示,是栈顶显示,只有在任务栈的顶部才会显示这个activity,其他activity是不能显示的,如果要显示,只能来到栈顶。
下面讲启动模式,至于为什么有启动模式这个玩意,其实,就是因为activity任务栈,有一些场景,会有一些问题,所以,才弄出来的一套解决方案。
如果,我直接,像网络上大多数资料那样,噼里啪啦,说一大堆这个模式那个模式之类的,小白看了,依然没什么卵用,因为,不知道拿来干什么的。所以,我下面,就会针对不同情况(可能不会讲完所有的,但平时常用的,我会讲),用不同的启动模式,还有怎么用,展开我的讲解。
首先说说,activity任务栈的缺点,我上面有提到,存放activity的集合的概念。集合,是一个管理,存放的好东西。但是,这玩意,有两个问题的。
1.如果存放的东西,太多,会导致内存放不下,就会出现经典的内存溢出(oom)
2.体验问题,我们销毁activity的时候,其实,就是把任务栈中对应的activity移除(弹出),先出现一个空白,然后再显示上一个页面(任务栈中的下一个activity),一个我们觉得很正常。但是,如果,我们想回到10个页面前呢?那就是出现10次空白,10次不是自己想要的页面了。那这个用户体验,可就差了。
当然,除了上面我说的比较明显两个缺点以外,在实际情况下,还会有其他问题的,这里就不说了,后面再说。
说启动模式之前,先聊聊这个启动模式怎么用,在哪里写。其实也简单,看下图吧:
很清晰吧,就是在清单配置文件中,在activity根节点里面如图操作就可以了。一共4种模式,编译器都帮你提示出来了。
好了,下面来说说使用场景的事情吧
先来说说standard模式,这个模式,也叫默认模式,就是按照任务栈的方式,压栈,弹栈,顺序进入和退出的方式,可以不写,因为,不写就是这个模式。
这个没什么好说的,不用其他三种模式,那就用它呗
再来说说,我平时都会用到的一种启动模式SingleTask
这个模式的从字面意思来说,就是单一的,唯一的。什么意思呢?就是说,这个模式下的activity,在任务栈中,只会有一个。那么问题来了,如果没有这个activity,那就正常创建正常放入任务栈就可以了,假如我这个activity在任务栈中,是在中间位置,现在我要看到这个activity,该怎么办呢?只能把这个activity弄到栈顶去。ok,在这个模式下,是把这个activity上面的所有activity都弹出,然后这个activity就到了栈顶了,就能显示了。
所以,总结一下:SingleTask,和默认standard模式的区别,就在于,在这个activity存在的情况下,想看到这个activity,就只有弹出它上面的所有activity。
这个模式,通常应用于主页activity,因为,通常主页activity,是整个app,从头到尾都会存在的activity,并且很多应用数据,都会在这个activity使用。
还有一点需要注意,就是在用intent传递数据的时候,如果目的地activity是SingleTask模式,activity的oncreat方法,是只会在第一次创建的时候调用,后面都不会再调用了(销毁后除外),这个时候,接收intent的,是另外一个方法了
@Overrideprotected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
下面来讲讲singleTop,这个模式,有一个特点,栈顶复用。
这个模式,有一个场景,用得特别多,就是新闻推送,显示新闻的页面,只有一个,但是,通常推送是很多的,而如果在栈顶就是这个新闻页面,那么这个页面是不会重复创建的,而是,重复利用这个界面。那么有同学就会问了,如果这个activity不在栈顶呢?ok,那么就会重新创建一个新的activity并放到栈顶。
和SingleTask有一点是一样的,就是当这个activity在栈顶的时候,这个activity是不会走oncreat,onstart方法,的要获取传入的intent,和上面一样。
这个使用场景嘛,很清晰了,就是应用与多推送,一个界面显示的情况下。
最后讲讲SingleInstance,这个模式,其实就是Android内存中只存在一个这样的activity。
举个例子吧,假如,有一个叫VIPActivity的是用的SingleInstance模式,那么,无论有多少个应用,要用这个VIPActivity,都只会调用唯一一个activity,这个activity是放到了一个特殊的任务栈里面,这个任务栈里面的东西,是大家共享的。这也很满足Android的设计尿性,最终都会有共享,开源的东西出现。讲真,这个模式,我一次没用过。
感觉写得不是很好,不过,也没办法了,以后再改进吧