在实际的项目开发中,我们需要根据特定的需求为每个活动指定恰当的启动模式。Activity的启动模式一共有4种:standard、singleTop、singleTask、singleInstance. 可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式
一、standard
standard模式是活动默认的启动模式,在该模式下,每启动一个活动都会创建该活动的一个新的实例并放在栈顶的位置,而不在乎返回栈里面是否已经存在该活动。
standard模式的示意图:
Java代码:
效果:点击三次button1按钮,都会打开FirstActivity活动界面,查看Logcat日志,可以看到创建了三个FirstActivity活动的实例,退出该活动界面需要点击三次Back键才退出。
二、singleTop
singleTop启动模式的工作原理:当每次启动活动时,系统会先在返回栈中检查栈顶的活动是不是当前正在启动的活动,如果是当前正在启动的活动,那么就会直接使用栈顶的这个实例,不会再创建新的实例,如果不是当前正在启动的活动,那么才会创建一个新的活动实例。
需要注意的是:如果栈内已经存在当前正在启动的活动,还是会重新创建一个新的活动实例。
singleTop模式的示意图:
情况一:正在创建的活动位于栈顶
Java代码:
修改AndroidManifest.xml中FirstActivity活动的启动模式:
运行程序:
在程序运行成功的时候,会创建一个FirstActivity活动的实例,然后我们点击button1,不管点击多少次,从Logcat日志中我们可以看到,除了刚开始运行程序的时候创建了一个实例外,没有再创建新的实例。
按Back键退出程序也只需要按一次Back键就行了。
情况二:返回栈内部存在当前正在启动的活动
两个活动:FirstActivity、SecondActivity
运行程序:因为启动了FirstActivity活动,所以此时只创建了一个FirstActivity活动的实例
点击button1按钮进入SecondActivity活动界面:创建了SecondActivity活动的实例
点击button2按钮,返回到FirstActivity活动界面:此时又创建了一个FirstActivity活动的实例。
经过 上面整个过程,返回栈中总共存在三个活动的实例,从栈底到栈顶依次是:FirstActivity--->SecondActivity--->FirstActivity
此时点击Back键,活动的运行顺序是:FirstActivity Back--->SecondActivity Back--->FirstActivity Back--->程序关闭
第一次点击Back:
第二次点击Back:
第三次点击Back:结束程序
三、singleTask
singleTask启动模式:每次启动一个活动时,系统会先检查返回栈中是否存在该活动,如果存在该活动,那么就会直接使用该实例,不会再创建一个该活动的实例,并使该活动之上的所有活动都出栈。如果不存在该活动,那么就会创建一个新的活动实例。
singleTask模式示意图:
示例:
第一步:将FirstActivity活动的启动模式设为singleTask模式
第二步:在FirstActivity活动中添加onRestart()方法,并打印日志
第三步:在SecondActivity活动中添加onDestroy()方法,并打印日志
第四步:运行程序,进入FirstActivity活动--->点击button1按钮进入SecondActivity活动界面--->点击button2按钮返回到FirstActivity
第五步:看Logcat日志,从日志中可以看到,运行程序的时候,只创建了FirstActivity活动的一个实例,当启动SecondActivity活动时,又创建了SecondActivity活动的一个实例,此时两个实例在返回栈中的位置是:FirstActivity活动的实例在栈底,SecondActivity活动的实例在栈顶。当点击button2按钮启动FirstACtivity活动时,此时SecondActivity活动实例被移除栈顶,因此调用了SecondActivity活动的onDestroy()方法,而FirstActivity活动从栈底位置到了栈顶位置,这个时候并没有再创建FirstActivity活动的实例,只是重新返回到了该活动,从不可见变为了可见状态,因此此时FirstActivity是调用了onReStart()方法,而没有调用初始化方法onCreate()方法。
四、singleInstance
场景:假设我们程序中的一个活动允许其他程序调用,如果我们想实现其他程序和我们的程序能够共享这个活动的实例,那么应该怎么实现呢?每个用于程序都有自己的返回栈,同一个活动在不同的返回栈中必然是创建了一个新的活动实例的,而我们共享的这个活动在一个返回栈中,共享同一个实例。
singleInstance启动模式:singleInstance启动模式与其它三种启动模式不同,它是通过创建一个新的返回栈来管理活动的(如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈),在这种模式下,会有一个单独的返回栈来管理活动,不管哪个应用程序来访问这个活动,都共用同一个返回栈,也就解决了共享活动实例的问题。
singleInstance模式的示意图:
示例:
第一步:将SecondActivity活动的启动模式设置为singleInstance
第二步:创建活动后,打印出FirstActivity活动、SecondActivity活动、ThirdActivity活动所在的返回栈
第三步:运行程序,进入FirstActivity活动界面--->点击按钮,进入SecondActivity界面--->点击按钮进入ThirdACtivity界面,打开日志,从日志中我们可以发现FirstActivity活动与SecondActivity活动都在返回栈16中,而SecondActivity活动在返回栈17中,也就是说在启动SecondActivity活动的时候,系统重新创建了一个返回栈17专门来管理活动SecondActivity.
第四步:此时在ThirdActivity活动界面点击Back键,就会直接回到了FirstActivity活动界面,这是因为返回栈16是我们运行程序的返回栈,在这个返回栈中只有FirstActivity和ThirdActivity两个活动,FirstActivity活动位于栈底,ThirdActivity活动位于栈顶,当点击Back键时,ThirdActivity活动出栈,FirstActivity活动就位于栈顶位置了,所以此时显示的是FirstActivity活动,而不是SecondActivity活动,紧接着再点击Back键,FirstActivity活动出栈,这时候就返回到了SecondActivity活动的界面,这是因为返回栈16已经空了,只剩下返回栈17,而返回栈17中只有SecondActivity一个活动,因此显示的就是SecondActivity活动的界面,然后再点击Back键,系统退出。
五、活动启动模式总结
1、standard:系统默认启动方式,所有活动在一个返回栈,每启动一个活动就会在返回栈的栈顶创建一个该活动的实例,与返回栈中有无该活动的实例无关。
2、singleTop:所有活动都在一个返回栈,每启动一个活动,系统会先检查返回栈的栈顶的活动是不是当前启动的活动,如果是,就直接使用,如果不是,就会创建一个新的活动实例,与栈顶以下是否存在该活动实例无关。
3、singleTask:所有活动都在一个返回栈,每启动一个活动,系统会先检查返回栈里面是否存在了该实例,如果存在,那么会把该实例上面的所有活动出栈,然后自己位于栈顶位置,如果不存在,那么会创建新的活动实例位于栈顶。(如果指定了不同的taskAffinity,也会启动一个新的返回栈)
4、singleInstance:通过创建一个新的返回栈来管理活动,可以达到不同的应用程序共享同一个活动的目的。