activity的启动模式一共为4种,分别是standard,singletop,singletask,singleInstance,我们可以在配置文件中通过给activity标签指定android:launchMode属性来选择启动模式。
1. standard
standard是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式,我们知道Android是使用返回栈来管理活动,每当启动一个activity,它就会在返回栈中入栈,并处于栈顶,直到下个activity入栈,对于使用standard模式的活动,系统不会去查这个activity是否已经在栈中存在,而是,每次这个活动被创建,每次都会有一个新的实例,每次实例都会入栈,然后每次返回退栈,都有一个实例被销毁,就会出现多次返回,多次是同一界面的情况,有多少个实例,就要按多少次返回键才能退出程序。
2. singleTop
我们发现standard模式不太合理,明明我们的activity已经在栈顶了,怎么启动还创建实例,这不就多余了吗,于是,我们想到了第二种模式,singleTop,它最大的区别就是当活动实例已经位于栈顶,则认为可以直接使用这个实例,不会再次创建新的activity实例。
但是有一点是当我们的activity没有处于栈顶的时候,我们再次启动这个activity,系统还是会创建实例,然后入栈,这样就出现了一个问题,我们这个activity没有位于栈顶,然后被再次创建实例入栈,那么之前的实例是什么结果呢,时被销毁了还是存在呢,通过程序运行结果可以知道,之前的实例不会被销毁,而是同时存在多个实例。当我们按返回键退出的时候,这两个实例也会被依次销毁。
3. singleTask
singleTop解决了standard的问题,但是也暴露了新的问题,如果该activity没有处于栈顶的位置,还是会创建多个活动实例的,那么有没有可能一个返回栈只有同一个activity的一个实例呢,这就要提到我们的第三种模式singleTask,当活动的模式为singleTask,每次启动该活动的时候系统会首先在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有就创建一个新的activity实例,则而言之,就是会检查是否存在实例,有的话就把在这个实例之上的其他activity的实例都出栈了,那么这个实例就来到了栈顶,没有的话,就创建一个实例,然后入栈。
4. singleInstance
最后一种模式是比较特殊的,不同于以上三种模式,上面的三种模式,无论怎么操作,都是在同一个返回栈,而singleInstance会启用一个新的返回栈来管理这个activity(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。
一个场景:我们把activityB设定为singleInstance的启动模式,然后activityA启动了activityB,然后activityB启动了activityC,打印日志可以看到activityA和activityC的返回栈id一样的,也就是说activityB的确是在另一个返回栈,当我们按下返回键时,此时我们的activityC是在当前显示,所以此时的返回栈是a和c在的栈,我们看到,从c返回了a,当我们再次按下返回键,又返回到了activityB,再次按下返回键才会退出,因为当我们从activityC按下返回键,activityC实例被销毁,此时本返回栈的栈顶实例是activityA,然后我们又按下返回键,activityA实例被销毁,本返回栈空了,开始显示另一个返回栈的栈顶activity实例,也就是activityB的实例,当我们按下返回键时,此实例被销毁,这个返回栈也空了,也就退出了程序。
附加;随时随地退出程序
怎么可以快速的退出程序,也就是快速的把所有的栈里activity的实例清空。
我们可以新建一个专门的集合类来对所有的活动进行管理。
public class ActivityCollector{
public static List<activity>activities=new ArrayList<>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for(Activity activity:activities){
if(!activity.isFinishing()){
activity.finish();}
}
}
}
我们新建了一个集合来暂存我们的activity,然后提供了添加和移除以及全部移除的方法;配合我们的baseactivity使用,这样每次新建一个activity继承于baseactivity,都会把这个activity添加到集合中,这样我们就可以对相应的activity进行管理,以及退出程序功能。
附加二:启动活动的优化写法
我们正常启动一个activity,都是通过显式intent,然后startactivity()这个方法,如果传参的话,就通过intent.putextra方法来添加数据,这是建立在我们知道我们需要传那些数据到哪个activity,如果不知道呢,所以,我们应该把我们需要的参数告诉别人,这样别人就能直接传参数给我们,而不用看代码,
public static void start(Context context,String data1,String data2){
Intent intent=new Intent(context,****.class);
intent.putExtra("",***);
intent.putExtra("",***);
context.startActivity(intent);
}
上面方法中,第一个参数为我们的跳转源,即我们在的页面,二三就是我们的要携带的参数。
在我们需要跳转到方法所在页面的地方调用这个方法。