Activity的启动模式浅析

2019-04-14 20:05发布

为什么Activity需要启动模式

         我们知道,在默认情况下,当我们多次启动同一个Activity的时候,系统会创建同一个Activity的实例,并把这些实例通通加入到同一个任务栈中,然后当我们按下back键时,这些相同的Activity的实例会逐个退出任务栈,任务是一种先进后出的栈结构,这时问题来了,为什么要创建这些相同的实例放到相同的任务栈中,显然,这种做法是不好的,为了解决这个问题,便产生了Activity的启动模式。下面将逐一介绍Activity的启动模式。

Activity的启动模式有哪些

        首先介绍一下任务栈的一个关键词TaskAffinity,任务相关性,这是Activity任务栈的第一个参数,他标识了Activity所需任务栈的名称;在默认情况下,所有的Activity所需任务栈名字为应用的包名;当然,我们可以通过TaskAffinity属性为每个Activity指定所需任务栈的名称,但有一点需要注意的是,我们所指定的任务栈的名称不能和应用的包名相同,不然将不会生效;下面开始介绍Activity的各种启动模式
        第一种:standard模式,标准模式,这也是系统默认的启动模式。在这种模式下,当我们启动一个或多个新的Activity,系统便会创建这些Activity的实例,并将这些实例加入到启动他的那个Activity的实例所在的任务栈中,并且每个Activity都会执行他相应的生命周期的回调,onCreate-->onStart--onResume;比如说我们新建Activity A;然后并不指定他的启动模式,这时这个Activity的启动模式都默认是standard模式,当我们在这个Activity里启动他本身,那我们每启动一次,就会创建一个新的实例并加入到他所在的任务栈中;如果我们启动三次,那么他所在的任务栈的情况是Activity A、Activity A、ActivityA; 这时,当我们按下Back键,Activity A会逐一退出任务栈,并回调onPause-->onStop-->onDestroy
        第二种:singleTop,栈顶复用模式,在这种模式下,如果新的Activity的实例一在栈顶,那么他将不会创建新的实例 并且不会回调他的生命周期的方法,因为他并未发生改变,相反,如果栈中已存在这个Activity,但并不位于栈顶,那么他将创建新的实例并压入栈顶,并且会回调生命周期对应的方法,假设我们创建四个Activity ABCD,A位于栈底,其次是A、C,D位于栈顶,当我们启动D,如果D的启动模式为singleTop,那么栈中的情况任然是ABCD,但如果D的启动模式是standard,那么栈中的情况将变成ABCDD,如果启动的是B,那么情况将变成ABCDB,因为B存在,但却未位于栈顶。         第三种 :singleTask,栈内复用模式,在这种模式下,只要任务栈中存在此Activity,那么不管你启动多少次,都不会创建此Activity的新实例,系统也会回调他的onNewIntent方法,比如说我们创建Activity A,当我们启动A的时候,系统会去寻找A需要的任务栈,如果任务栈存在,系统再去寻找这个任务栈中是否存在A的实例,如果存在,将不会创建A的实例,如果不存在,将创建A的实例,并放入栈中;如果不存在A所需的任务栈,那么系统将创建A所需要的任务栈,并创建A的实例并放入任务栈中。需要注意的是,这种模式下的Activity的出栈顺序,例如:当前栈中有四个Activity的实例ABCD,如果B的启动模式是singleTask模式,此时启动B,那么C、D都会出栈         最后一种是singleInstance模式,单实例模式,这种模式具有singleTask模式的所有特性,唯一不同的是在这种模式下,Activity的实例只会存在在一个单独的任务栈中,比如创建Activity A,当启动模式为singleInstance模式时,启动A,系统会为A创建一个单独的栈,并创建A的实例,并将A放如这个栈中,后续不管启动多少次A,都不会创建A的实例。除非A所在的任务栈被销毁。

如何应用

  好了,Activity的四种启动模式都介绍完了,接下来我们看看如何应用,首先来看看如何来设置Activity的启动模式。Activity的启动模式有两种方式,第一种是通过manifests配置文件进行设置
<activityandroid:name=".secondActivity"android:launchMode="singleTask"/> 这样就将secondActivity的启动模式设置成了singleTask模式了   另一种方式是通过在Intent中设置标志位来为Activity指定启动模式,同样secondActivity的启动模式可以这样来指定; Intent intent =newIntent(this,secondActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 这两种方式设置Activity的启动模式的效果是一样的,但两种方式也有所不同,首先,优先级不同,第二种方式指定的优先级高于第一种,当两种方式同时存在时,以第二种的为准,另外,两种方式的指定范围不同,第二种无法指定singleInstance模式,第一种无法设置FLAG_ACTIVITY_CREAR_TOP标识  我们知道如何了如何指定Activity的启动模式后,那么我们该怎么指定Activity所需的任务栈呢,很简单,通过manifests中设置Activity的taskAffinity属性即可,如: <activity android:name=".secondActivity" android:launchMode="singleTask" android:taskAffinity="task1" /> 这样就指定了secondeActivity的的任务栈的名称为task1了,最后补充一点,当前一个Activity启动第二个Activity的时候,后一个Activity和前一个位于同一个任务栈中,此时后一个Activity拥有和前一个Activity相同的栈的名称;

后序

   此篇文章只作个人学习笔记,不喜勿喷。如若有幸帮到各位小伙伴,固然欣喜,若有错误,还望各位大侠指点一二。鄙人将不胜感激;