首先我想说,这是一个老生常谈的问题,网上说一翻一大片,原因有二:
- 这个东西不难,因为它很基础
- 这个东西很重要
然而从自身角度出发,还是很有必要去深入地,详细地去理解一下这它。
首先我们就去源码里面扒一扒,Andriod是怎么样获取这个lanchMode的。
之前大致把Activity的启动流程图(基于Android sdk 23) 通过泳道图的形式画了一下,
那么基本上可以断定的是,关于launchMode这块的逻辑应该是在ActivityStackSupervisor
这个类,因为里面涉及到stack
的操作,在看ActivityStackSupervisor
这个类,Activity的launchMode是在resolveActivity
这个方法里面实现的,继续看代码却发现是一头雾水,在这里只有使用它的地方,却没有发现哪里去获取生成它的地方后来进行了一次全局搜索,发现了PackageParser
这个类,里面有一句代码:
a.info.launchMode = sa.getInt(R.styleable.AndroidManifestActivity_launchMode, ActivityInfo.LAUNCH_MULTIPLE);
再去看一下ActivityInfo.LAUNCH_MULTIPLE里面的注释,
/***
* Constant corresponding to <code>standard</code> in * the {@link android.R.attr#launchMode} attribute.
*/
那么这里就可以解释,默认值为standard的问题。对于PackageParser的调用时机,这里不做说明,具体参考
http://blog.csdn.net/Luoshengyang/article/details/6766010。
目前Activity中共有四种启动模式: standard
、singleTop
、singleTask
、singleInstance
standard
标准模式,也是默认模式,它的表现特点,在同一个任务栈里面,可以出现多个实例;每个实例也可以属于不同的任务栈。换句话说,就是这个实例是被放在启动它的任务栈里面去。这个其实也很好理解,通俗一点讲就是,我启动一次,就创建一个实例,我再启动一次,再去创建一次。
singleTop
栈顶复用,字面去理解,就大致上可以知道如果当前启动的这个Activity,它属于栈顶,那么就用原先那个,如果不是属于栈顶即使它的实例已经存在,那么跟standard模式表现是一样的。而对于复用的Activity,它就不会去执行原有的Activity的生命周期,而是直接去执行Activity里面的onNewIntent()方法。事实上这种情况在实际开发中用到的并不是很多。
singleTask
栈内复用,那么它跟singleTop的区别是,只要栈内有目标Activity对应的实例存在,那么它就会复用先前的实例,那么当实例不在栈顶的时候,那么就需要把在它上面面的其他实例给一一出栈。
singleInstance
网上看到很多人是这么描述singleInstance的,它是singleTask的加强版,singleTask是对于一个任务栈来说的,而singleInstance则是基于整个系统来说的,假设应用A里面有Activity: a1, a2, a3,其中a1声明为singleInstance,a1启动a2, a2启动a3,应用B里面的activity想要去调用应用A里面的a1,因为a1声明为singleInstance,那么当应用B启动a1的时候,a2,a3必然也会被它从原先的A的任务栈里面移除。