Activity启动模式详解

Activity的启动模式有四种:

  1. standard(标准模式,也是Activity的默认启动模式)
  2. singleTop(栈顶复用模式)
  3. singleTask(栈内复用模式)
  4. singleInstance(单实例模式)

下面对这四种启动模式进行详细的介绍:

standard:

standard模式是Android默认的启动模式,在AndroidManifest.xml定义Activity的时候,如果没有指定启动模式,那么该Activity将默认使用此模式。该启动模式表示,在启动一个新的Activity的时候,不论Activity的栈中有没有当前Activity的实例,都会创建一个新的Activity实例添加到Activity的栈中。其伪代码如下;

1
2
3
public void standardMode() {
activityStack.add(new SpecificActivity());
}

singleTop:

栈顶复用模式,使用这种模式的Activity在启动时会首先检查Activity的栈顶, 如果存在一个该Activity的实例,则不会创建新的Activity, 而是使用栈顶的Activity实例(需要注意的是:使用栈顶的Activity实例时,并不会重新执行Activity的生命周期方法,而是执行onNewIntent()方法, 可以在此方法中接收相应的值);否则将创建新的Activity实例,不管Activity的栈中是否有当前Activity的实例。即该模式只会检查栈顶实例。其伪代码如下;

1
2
3
4
5
6
7
8
public void singleTopMode() {
topActivity = activityStack.get(activityStack.size()-1);
if (topActivity instanceOf SpecificActivity) {
topActivity.onNewIntent();
} else {
activityStack.add(new SpecificActivity());
}
}

singleTask:

栈内复用模式,使用这种模式的Activity在启动的时候会先检查Activity栈,如果在Activity的栈中发现已存在当前Activity的实例,则使用栈中的Activity实例,并执行该实例的onNewIntent方法。否则将创建新的Activity实例。需要注意和singleTop区别的是:singleTop只检查栈顶的实例, 而singleTask会检查整个Activity栈,一旦发现有实例存在,就不再创建新的实例,同时,在使用Activity栈中已存在的实例时,会讲改实例到栈顶的所有其他实例移出栈空间。其伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void singleTask() {
int index = -1;
for (int i = activityStack.size()-1; i >= 0; i--) {
if (activityStack.get(i) instanceOf SpecificActivity) {
index = i;
break;
}
}

if (index != -1) {
for (int i = index + 1; i < activityStack.size(); i++) {
activityStack.remove(i);
}
activityStack.get(index).onNewIntent();
} else {
activityStack.add(new SpecificActivity());
}
}

singleInstance:

单实例模式,可以认为是singleTask的升级版,除了具有singleTask的所有特点外,其最重要的一个特性就是,在创建Activity实例的时候,还会为其单独创建一个Activity栈。其伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public void singleTask() {
// 先创建栈
if (SpecificActivityStack == null) {
SpecificActivityStack = createStack();
}
// 因为使用这种模式的Activity都拥有单独的栈空间,所以每个栈空间中只有一个Activity实例
if (SpecificActivityStack.get(0) != null) {
SpecificActivityStack.get(0).onNewIntance();
} else {
SpecificActivityStack.add(new SpecificActivity());
}
}

使用场景

  1. stardard模式是默认的启动模式,一般情况下,我们在项目开发过程中不会对Activity指定启动模式,所以基本上项目中的大多数的Activity都采用的这种模式;
  2. 目前市场的App,大多数都采用的Tab+Viewpager+Fragment的模式构建的App的主页,而这种模式的主页的启动模式一般都是singleTask模式,因为我们只需要一个主页实例;
  3. singleTop模式基本都是用来解决重复创建实例问题的,一般情况下用的比较少。但是在推送通知和支付中比较长见,比如微信支付的WXPayEntryActivity的启动模式就是singleTop;再比如推送的情况,当你接收到一个推送后,点击后会跳转到相应的Activity, 当你跳转之后,又收到了一条推送通知,此时跳转的是同一个Activity,此时我们就可以考虑使用singleTop模式,否则不断的点击推送通知,将会不断创建新的Activity实例;
  4. singleInstance模式的使用场景非常罕见。如果一个Activity要实现全局的功能点,但是又不想被其他的Activity影响(有点像Service),此时就可以考虑使用singleInstance模式了。比如QQ在锁屏情况下的消息弹窗,其实就是一个Activity(只不过对Window对象进行了设置),因为它要一直处于运行中,就要求不能被其他的Activity的影响,此时使用singleInstance最好不过了。通俗来说,如果你需要Activity像Service一样一直处于Running状态时,就可以考虑使用singleInstance模式了

总结

妙用Activity的启动模式,有时可以起到事半功倍的效果,并且简化我们的需求,提高开发效率。具体使用哪种启动模式,还是要根据需求具体对待。

,