activity一共有4种启动模式:standard,singleTop,singleTask,singleInstance,在配置文件中,通过给activity设置android:launchMode属性,来选择启动模式
android是通过使用返回栈来进行管理activity的。
standard模式
activity默认是standard模式,在standard模式下,每当启动一个新的activity它都会在返回栈中入栈,并处于栈顶的位置,系统不会在乎这个活动是否已经在栈中存在,每次启动都会创建该活动的一个新的实例。
singleTop模式
singleTop模式的activity,在启动活动时,如果发现返回栈的栈顶已经是该活动,则系统认为可以直接使用它,而不会再创建新的活动实例。但是,如果该活动虽然已经存在于返回栈中,但是并不是在栈顶的位置,此时,就会创建新的活动实例并置于栈顶位置,可以发现,此时回退栈中存在一个activity的两个实例;
使用singleTop模式,可以很好的解决,重复创建栈顶活动的问题,但是如果该activity实例没有存在于栈顶位置,还是会创建多个活动实例的,有没有办法让某个活动在整个应用的上下文中只存在一个实例呢,当然没问题,singleTask模式解决这个问题。
singleTask模式
设置为singleTask模式的activity在启动实例的时候,系统首先会在回退栈中检查,是否存在该activity的实例,如果发现已经存在则直接使用该实例,并且把在这个活动之上的所有活动统统出栈,如果没有发现,才创建一个新的实例;
有一个值得注意的问题:如果回退栈中已经存在该activity实例了,但是不在栈顶,他上面的所有活动全部出栈(destroy掉了),让他处 于栈顶,此时他的生命周期,走的的是onRestart方法启动的该活动;那些出栈的活动,毫无疑问的被直接销毁掉了。
这里需要注意的是:这个回退栈中存在是因为之前启动过,而没有销毁掉,如果因为某些原因,比如系统因为内存不足将这些不可见的活动的实例回收掉了,那肯定在回退栈中没有啦,启动activity,肯定会创建一个新的activity实例了。
singleInstance模式
singleInstance是四种模式中最特殊最复杂的,不同于其他三种模式,指定为singleInstance的activity,会启用一个新的返回栈来管理这个活动;
这样做有什么鸟用?当然有鸟用,比如说:我们的程序中有一个活动是允许其他程序调用的,如果想实现其他程序和我们的程序可以共享这个活动的实例,该如何操作呢?之前三种模式好像不行,因为每一个应用程序都会有自己的回退栈,同一个活动在不同的返回栈中入栈时,必然是创建了新的实例。使用singleInstance模式,就可以解决这个问题,这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都公用一个返回栈,就解决了不同应用程序共享活动实例,共同管理活动实例的问题。
有一个这样的问题:
对于这singleInstance模式的activity到底有没有真的重新有一个单独的返回栈来管理它,我们可以直接getTaskId()来获取当前activity实例的返回栈id,如果不同的id,那当然毫无疑问就是不同的返回栈嘛,事实也是如此;
问题是:现在有3个activity,one,two,three,把two设置为singleInstance模式,启动顺序分别是one里有一个按钮,点击启动two,然后two里有一个按钮,点击启动three,
当一次从one,启动two,启动three,点击back按钮时候,会发生什么呢?
你会看到,当在three,按下back,直接回退到了one,再按下back,one消失,two出现了,继续按下back键,程序退出了。
为啥是这样呢?
其实不难理解,one和three放在一个返回栈里,three随着按下back出栈了,one到了栈顶;再按下back,one出栈,这个返回栈空了,于是就显示了另一个返回栈的栈顶的活动,也就是two。最后再按一次back,所有返回栈都空了,程序自然也就退出了嘛。