一说到启动模式,大家都认为这是Android里面最基本的东西,这些东西自己很清楚,但是真正用起来的时候可就懵逼了,我也是在使用的时候才发现自己并不是那么清楚,所以才整理成一篇文章方便自己和大家能更好的理解。
一、lanchMode
Activity启动模式是指在清单文件中配置lanchMode,比如
<activity android:name=".MainActivity"
android:launchMode="singleTop"/>
Activity启动模式分为4种
1. standard(标准模式)
系统默认的启动模式,每次启动Activity都会创建新的实例,不管任务栈中是否存在该实例。
2. singleTop(栈顶复用模式)
如果要启动的Activity实例已经位于任务栈的栈顶,那么再启动这个Activity就不会创建新的实例,会复用栈顶的实例(不会走onCreate),然后回调Activity的onNewIntent方法
反之,如果要启动的Activity实例存在但是没有位于任务栈的栈顶,那么也会重新创建新的Activity实例。
3. singleTask(栈内复用模式)
如果要启动的Activity在任务栈中存在,那么再次启动这个Activity就不会创建新的实例,直接销毁掉该Activity之上的Activity,然后该Activity回到栈顶,并且回调onNewIntent方法,即在该应用的任务栈中只会存在一个该Activity的实例。
4. singleInstance (单栈单实例模式)
此模式的Activity只能单独位于一个任务栈中,并且这个任务栈只有它自己
二、Intent.Flag
Intent.flag是指在使用代码启动Activity的时候,显式的为Intent指定Flag,这个Flag跟launchMode是两回事,它们两个是 【相互辅助】 来起作用的
1. FLAG_ACTIVITY_NEW_TASK
在理解该flag之前,我们需要知道Activity的亲和力 taskAffinity
affinity: 具有相同的affinity的多个Actvity理论上属于一个task,默认情况下,一个应用内的所有Activity都具有相同的affinity,都是从Application(taskAffinity)继承而来,Application默认的affinity是应用的包名。
所以,该flag的作用是根据Activity 的Affinity判断是否需要创建新的任务栈,然后再将要启动的Activity放进去,如果不单独指定affinity的话,如果应用没启动,才会创建新的任务栈,如果应用已经启动,就不需要创建新的任务栈了。
应用:这个模式通常应用于我们的通知点击启动Activity,因为通知点击给的Context是属于ApplicationContext的,因为非Activity类型的Context并没有任务栈,所以直接启动Activity会报错,这个时候就需要制定该flag,这样如果任务栈不存在启动的时候就会创建一个新的任务栈,如果存在直接根据亲和力将其压入栈中。
2. FLAG_ACTIVITY_CLEAR_TASK
清除任务栈,并且将该Activity放入栈底,该flag需要跟FLAG_ACTIVITY_NEW_TASK配合使用。
这种情况下不管要启动的Activity的启动模式是singleTop还是singleTask,都会清空任务栈,重新创建新的实例,即->使用此flag,launchMode将会失效。所以它应用在想完全重启首页而不想受launchMode影响的情况下。
3. FLAG_ACTIVITY_CLEAR_TOP
表示要启动的Activity会将任务栈中其之上的Activity都强制出栈,但是在不同的启动模式下,表现出来的栈的改变是不相同的,如下:
launchMode是standard情况下使用该flag: 如果任务栈中已经存在该Activity的实例,那么会清除这个实例和它之上的activity,然后创建新的实例入栈。 即如果此时栈离有 A->B->C->D ,此时以standard模式下使用该flag启动B,那么会将B,C,D全部销毁掉,然后创建新的B,最终任务栈为 A->B(新)
launchMode是singleTop或singleTask情况下使用该flag: 如果任务栈中已经存在该Activity的实例,那么会清除和它之上的activity,然后回调该实例的onNewIntent,即如果此时栈离有 A->B->C->D ,此时以singleTop或singleTask模式下使用该flag启动B,那么会将C,D销毁掉,然后回调B的onNewIntent,最终任务栈为 A->B(旧)。
4. FLAG_ACTIVITY_SINGLE_TOP
该模式与启动模式的singleTop相同,如果栈顶有,则重复利用,回调onNewIntent。