Activity的四种启动模式详解

Activity的启动模式

1. 启动模式的类别

  • 标准模式(standard)
  • 栈顶复用模式(singleTop)
  • 栈内复用模式(singleTask)
  • 单例模式(singleInstance)

2. 任务栈

任务栈Task,是一种用来放置Activity实例的容器,他是以栈的形式进行盛放,也就是所谓的先进后出,主要有2个基本操作:压栈和出栈,其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity。默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示它。当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,手机页面显示的就是前台任务栈中的栈顶元素。

3. 四种启动模式的解释

standard

标准模式:在清单文件中声明 Activity 时,如果不设置Activity的启动模式,系统会 默认 将其设置为standard。每次启动一个标准模式的Activity都会重新创建一个新的实例,不管这个Activity之前是否已经存在实例,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈,谁启动了这个Activity,那么这个Activity实例就运行在启动它的那个Activity所在的栈中 。根据上面所说,我们就了解了当用ApplicationContext启动或者在Service中直接调用startActivity启动标准模式Activity时报如下错误的原因了。

android.util.AndroidRuntimeException: Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

上面错误的原因就是被启动的Activity是标准模式,而发起启动请求的Context不是Activity的Context,未存在Activity栈,而每个Activity实例启动销毁都需要进栈出栈,用栈来存储Activity的信息,所以非Activity Context需要设置FLAG_ACTIVITY_NEW_TASK属性,启动一个新的Activity栈。

singleTop

栈顶复用模式:在这种模式下,如果新启动的Activity已经位于任务战的栈顶,那么此Activity不会被重新创建,只会重新调用 onNewIntent 方法,这个Activity的onCreate、onStart都不会被系统调用。如果新Activity实例已经存在但不在栈顶,那么重新创建 Activity 并放入栈顶。

singleTask

栈内复用模式:这是一种单实例模式,一个栈中同一个Activity只存在唯一一个实例,无论是否在栈顶,只要存在实例,都不会重新创建,和 singleTop 一样会重新调用 onNewIntent 方法。需要注意的是:如果一个Activity被设置为singleTask模式,那么当栈内已经存在该Activity实例时,再启动该Activity,会让该Activity实例之上的Activity被出栈。举个例子:有四个Activity 分别是 A、B、C和D,A是singleTask模式,当先执行A->B->C->D时,A在栈内已存在实例,此时再调用D->A启动A时,会让A实例之上的B、C、D都出栈。一般项目的MainActivity都设置为此模式,方便放回首页和清空中间Activity。

singleInstance

单实例模式:这是一种加强的singleTask模式,它除了具有singleTask模式的所有特性外,还加强了一点,那就是此种模式的Activity只能单独地位于一个任务栈中,不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。

4. 启动模式的设置

启动模式有2种设置方式:在AndroidMainifest设置、通过Intent设置标志位

4.1 在AndroidMainifest设置

AndroidMainifestActivity配置进行设置


4.2 通过Intent设置标志位

Intent inten = new Intent (ActivityA.this,ActivityB.class);
//通过Intent的Flag设置
intent,addFlags(Intent,FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); 

​ 标记为属性

标记位属性 含义
FLAG_ACTIVITY_SINGLE_TOP 指定启动模式为栈顶复用模式(SingleTop
FLAG_ACTIVITY_NEW_TASK 指定启动模式为栈内复用模式(SingleTask
FLAG_ACTIVITY_CLEAR_TOP 所有位于其上层的Activity都要移除,SingleTask模式默认具有此标记效果

你可能感兴趣的:(Activity的四种启动模式详解)