Activity的启动模式简介

在Android的Activity中,有4种不同的启动模式,分别是standard、singleTop、singleTask、singleInstance,可以在AndroidManifest.xml中通过给标签指定android:launchMode属性来选择启动模式。

在Android系统中,通过task(任务)来管理Activity,任务就是存放了一些Activity的栈,处于栈顶的Activity实例总是可见并可交互的,每启动一个新的Activity就把Activity的实例放在栈顶,销毁一个Activity就把Activity实例从栈顶出栈,所以也成为返回栈(back task)。不过,在singleInstance模式中,也会出现多个返回栈。

standard

standard是Android默认的启动模式,在不显式指定的情况下,Activity都使用standard模式启动。

使用standard模式的Activity,无论这个Activity是否已经在返回栈中存在(拥有一个实例),每次启动都会创建一个该Activity的实例,并放入栈顶。

standard模式下,在FirstActivity中启动FirstActivity并输出taskId 和this指针,可以发现两次启动的FirstActivity并不是同一个对象,这两个对象都存在返回栈中。

  1. // onResume中输出taskId和this
  2. taskId 109, this com.rookiegan.myapplication.FirstActivity@132e1b8
  3. taskId 109, this com.rookiegan.myapplication.FirstActivity@5c2fd8e

singleTop

singleTop模式下,启动Activity时如果发现返回栈的栈顶已经是该Activity了,就直接使用它,不会再创建新的实例。

singleTop模式下,在FirstActivity中启动FirstActivity并输出taskId 和this指针,可以发现两次启动的FirstActivity是同一个对象,返回栈中只存在一个FirstActivity实例。

  1. // onResume中输出taskId和this
  2. taskId 112, this com.rookiegan.myapplication.FirstActivity@132e1b8
  3. taskId 112, this com.rookiegan.myapplication.FirstActivity@132e1b8


singleTop模式下(FirstActivity为singleTop模式,SecondActivity为standard模式),在FirstActivity中启动SecondActivity,又再SecondActivity启动FirstActivity,可以发现两次启动的FirstActivity不是是同一个对象,返回栈中只存在2个FirstActivity实例,这是因为第二次启动FirstActivity时SecondActivity在栈顶,于是重新创建一个FirstActivity的实例,此时返回栈中共有三个Activity实例。

  1. // onResume中输出taskId和this
  2. taskId 114, this com.rookiegan.myapplication.FirstActivity@132e1b8
  3. taskId 114, this com.rookiegan.myapplication.SecondActivity@71b69af
  4. taskId 114, this com.rookiegan.myapplication.FirstActivity@308567f

singleTask

singleTask模式下,每次启动该Activity时,系统首先会检查返回栈中是否有该Activity的实例,如果发现已经存在,则直接使用该实例,并把这个Activity之上的所有其他Activity全部出栈。

singleTask模式下(FirstActivity为singleTask模式,SecondActivity为standard模式),在FirstActivity中启动SecondActivity,又在SecondActivity启动FirstActivity,可以发现两次启动的FirstActivity是同一个对象,FirstActivity第二次启动时将FirstActivity之上的SecondActivity出栈,此时返回栈中共有1个Activity实例。

  1. taskId 116, this com.rookiegan.myapplication.FirstActivity@132e1b8
  2. taskId 116, this com.rookiegan.myapplication.SecondActivity@71b69af
  3. taskId 116, this com.rookiegan.myapplication.FirstActivity@132e1b8

singleInstance

指定为singleInstance模式的Activity会启用一个新的返回栈来管理这个Activity。如果singleTask模式制定了不同的taskAffility,也会启动一个新的返回栈。如果有其他程序和我们的程序共享同一个Activity,就需要这种模式。

指定FirstActivity和ThirdActivity为standard模式,SecondActivity为singleInstance模式,在FirstActivity中启动SecondActivity,又在SecondActivity启动ThirdActivity,可以发现FirstActivity和ThirdActivity是同一个返回栈,而SecondActivity是不同的返回栈。此时点击三次返回键,Activity的顺序是ThirdActivity -> FirstActivity -> SecondActivity -> 桌面,因为FirstActivity和ThirdActivity在同一个返回栈中,ThirdActivity出栈后所在返回栈就剩下FirstActivity,FirstActivity出栈后就到存放SecondActivity的返回栈中

  1. taskId 123, this com.rookiegan.myapplication.FirstActivity@132e1b8
  2. taskId 124, this com.rookiegan.myapplication.SecondActivity@71b69af
  3. taskId 123, this com.rookiegan.myapplication.ThirdActivity@a21b64c

此时,如果有其他App通过隐式Intent的方式来启动SecondActivity,其他App也将会使用和上例SecondActivity同样的返回栈和和实例。

  1. taskId 146, this com.rookiegan.myapplication.MainActivity@132e1b8
  2. taskId 146, this com.rookiegan.myapplication.MainActivity@132e1b8
  3. taskId 148, this com.rookiegan.myapplication.SecondActivity@3001c9f //本App启动SecondActivity
  4. taskId 146, this com.rookiegan.myapplication.ThirdActivity@4a54a7c
  5. taskId 148, this com.rookiegan.myapplication.SecondActivity@3001c9f //其他App来启动SecondActivity