Activity的启动模式和常见Flag组合

众所周知,Activity是Android四大组件之一,且应是初级程序员最先接触使用的Android技术,当然也会较早知道Activity有四种启动模式,但是可能对其了解不深,即使部分几年工作经验的开发由于业务方向等也不一定清楚其原理。
首先,要明确,Android为何要给Acitivity设计这个东西呢。我们程序开发在学习数据结构时都学过形形色色的数据结构,不同的数据结构都有不同的优缺点,和适用场景。而且后讲的数据结构基本是为了解决前边数据结构的部分缺点而设计的。首先树立一个观念,Android中的设计都是为了适用特定使用场景或解决某种问题,或者说效率问题或者空间问题而设计的,所以清楚的了解其原理和优缺点,对我们的开发有很大的促进作用。
任务栈,是一种“后进先出”的栈结构。

四种启动模式

1)Standard:标准模式,默认启动模式,每次启动一个activity都会重新创建一个新实例,不管是否已有实例。即使从ActivityA startActivity ActivityA,也会再次创建A的实例放于栈顶,当回退时,回到上一个ActivityA的实例。
此模式是一种多实例实现方式,一个任务栈可以有多个实例,每个实例也可以属于不同的任务栈。谁启动了这个Activity,那么其就运行在启动它的那个Activity所在的栈中。而正因为如此,如果我们使用ApplicationContext去启动standard模式的Activity时必须要带FLAG_ACTIVITY_NEW_TASK的flag,由于使用application context非Activity类型的context,就没有任务栈,所以需要增加那个flag标记,意思是创建一个新的任务栈。

2)SingleTop:栈顶复用模式。如果新Activity已经位于任务栈的栈顶,那么此Activity则不会被重新创建,同时会回调onNewIntent方法,但是其onCreate,onStart不会被调用,因为未发生改变。即不会走onCreate->onStart,会直接进入ActivityonPause->onNewIntent->onResume 方法但是如果新Activity实例不在栈顶,则还会重新创建,此时又类同于standard会重新创建实例。
3)SingleTask:栈内复用方式。如果栈中存在此Activity实例,多次启动此Activity实例不会创建新的实例,栈内在此实例之上的Activity都会出栈(clear top效果),直到当前Activity到达栈顶,并执行onNewIntent方法。如果栈中不存在此Activity实例,则重新创建并压入栈中。
4)SingleInstance:单实例模式,其具有singleTask的所有特点并且此模式只能单独位于一个任务栈中。整个Android操作系统中最多只有一个该Activity实例存在,如果task中存在实例,执行其onNewIntent方法。

指定启动模式方式


第一种方法: 通过AndroidMenifest.xml指定。

<activity android:name=".activity.MainActivity" android:launchMode="singleTask"/>

第二种方法:

Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
二者的区别是,
1.第二种方法的优先级高于第一种,两种同时存在时,则以第二种为准。
2.限定范围不同,第一种无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种方式无法为Activity指定singleInstance模式。

笔者曾在这里走过坑,开始不知道两种设置是互斥有优先级的,一直在怀疑为何xml里设置的模式不管用,其实由于启动时有New_task的flag,,已经确定为singletask的模式了,而且还加了FLAG_ACTIVITY_CLEAR_TASK(当时对此只看字面不理解)。且由于设置了透明主题背景,在onpause中判断为界面已消失(其实onpause不代表界面不可见),此时还未进入onstop,又要启动时,此Activity会重新创建。
即ActivityA的上一个实例进入了onpause,还未onStop, 又启动一个新的ActivityA实例,由于clear_task标记的存在,会销毁当前栈,oncreate-onstart-onresume, 然后上一个实例进入onstop,在这个onstop中又释放了一些资源,导致问题。后来不得不检测是否是最新实例,才释放资源。

Activity的Flag

FLAG_ACTIVITY_NEW_TASK
同XML中指定为singleTask模式

FLAG_ACTIVITY_SINGLE_TOP
同XML中指定为singleTop模式
FLAG_ACTIVITY_CLEAR_TOP
当具有此标记的activity启动时,同一个任务栈上所有的Activity都要出栈。一般和singleTasK模式一起出现。如实例存在,调用onNewIntent。singleTask默认就有此标记的效果。
FLAG_ACTIVITY_CLEAR_TASK
该模式必须配合FLAG_ACTIVITY_NEW_TASK一起使用,效果就是:
**如果目标task已经存在,将清空已存在的目标Task,否则,新建一个Task栈,之后,新建一个Activity作为根Activity。**Intent.FLAG_ACTIVITY_CLEAR_TASK的优先级最高,基本可以无视所有的配置,包括启动模式及Intent Flag,哪怕是singleInstance也会被finish,并重建。

发布了17 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/caizehui/article/details/104178425
今日推荐