第一节 activity的launchMode
前言:
activity为什么需要启动模式呢?
答:我们知道,在默认情况下,我们多次启动同一个activity,系统会创建多个实例并把他们一一放入到任务栈中,这样不是很傻么.所以在android在设计的时候也考虑到这个问题,因此它提供了启动模式修改系统的默认行为
什么是任务栈?
答:任务栈是一个activity的集合,系统使用栈的方式管理activity,具有先进后出的特性,当我们打开一个新的activity或者退出当前的acticity后会在栈中添加或者减少一个activity组件,android系统通过任务栈有序的管理activity组件,并且只有位于栈顶的activity才能与用户交互;当我们退出应用程序时,必须把任务栈中所有的activity组件清除出栈,任务栈才会被销毁,当然任务栈也可以位于后台,并且保留了每个activity的状态;需要注意的是,一个app可能有多个任务栈,同一个任务栈内的activity有可能来自不同的app
正文:
activity的四种启动模式:
standard:标准模式,这也是系统默认的启动模式;一个任务栈中可能有多个实例;谁启动了这个activity,它就和谁在一个任务栈中,比如activity A启动了activity B,B就进入了A的任务栈中,当我们用ApplicationContext启动标准模式的activity会报下面的错误:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
这是因为标准模式的activity会进入启动它的activity的任务栈中,而context并没有所谓的任务栈,所以会报错.
解决这个问题的方法是为待启动的activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为它创建一个新的任务栈,这个时候实际上是以singleTask模式启动的
singleTop:栈顶复用模式.在这种模式下,如果新activity位于栈顶,再次启动它,会调用onNewIntent方法,不会再创建新的实例,如果不在栈顶会创建新的实例
singleTask:栈内复用模式,这是一种单实例模式,当请求此模式下的activity启动,首先会判断它所需的栈是否存在,如果不存在,则创建新的栈和它的实例,如果存在,判断栈内是否已存在它的实例,如果不存在它的实例创建新的实例,如果存在调用它的onNewIntent方法,并且把它提到栈顶和clearTop.也就是它上面所有的actiivty全部出栈
singleInstance:单实例模式,这是一种加强了的singleTask模式,具有此模式的activity只能单独位于一个任务栈中
这里指出一种特殊的情况:
假设有两个任务栈,前台任务栈的情况为AB,后台任务栈的情况为CD,CD的启动模式均为singleTask,当请求启动D,后台任务栈会变为前台任务栈,栈内所有的activity会进入前台任务栈
假设有两个任务栈,前台任务栈的情况为AB,后台任务栈的情况为CD,CD的启动模式均为singleTask,当请求启动C,C会先clearTopD,后台任务栈会变为前台任务栈,C进入前台任务栈
此笔记的最后一个知识点:TaskAffnity
TaskAffnity,可以翻译为任务相关性,这个参数标识了一个activity所需要任务栈的名字,名字必须和包名不同才有意义,因为系统默认的任务栈名字为包名!此属性主要和singleTask和allowTaskReparenting属性配合使用