Activity 的四种启动模式

在Android系统中我们创建的Activity是以栈的形式存放在任务栈里,根据启动模式的不同,任务栈的存放方式有所区别。Activity有四种不同的启动模式,根据实际使用场景要选择不同的适合的启动模式。

设定Activity可以在清单文件中配置:

1
2
3
4
5
6
7
<activity android:name=".Activity.MainActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

也可以在启动Activity的代码中进行设定:

1
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

Standard ,默认的启动模式,标准模式

开启这个Activity,系统就会new一个新的Activity,这个Activity的引用就会出现在当前任务栈的顶部

注意:不能使用 getApplicationContent 去开启一个 Standard 模式的 Activity,这样会报错。因为通过 getApplicationContent 获取的 context 不是 Activity 类型,没有任务栈。正确的做法是为开启的 intent 添加 FLAG_ACTIVITY_NEW_TASK 标志,也就实际以 singleTask 模式启动。

Singletop 顶部复用模式

如果开启的Activity已经存在一个实例在任务栈的顶部,再去开启这个Activity,系统就不会创建新的Activity的实例了,而是会调用onNewIntent()复用已经存在的这个Activity,通过该方法可以接受重新传入的参数。但是如果要开启的 Activity 的引用不是位于栈顶,那么仍然会新创建一个实例。
目的: 避免奇怪的用户体验
案例: 浏览器的书签

SingleTask 单一任务栈

如果任务栈里面已经存在要激活的Activity,就不会重新创建,而是跟singleTop一样回调onNewIntent方法传入新的的参数。
直接复用这个已经存在的Activity,并且把这个Activity上面其他的所有的Activity清空掉.
使用案例: 浏览器的BrowserActivity
目的: 如果一个Activity非常笨重(开销非常大)

SingleInstance 单一实例(单例)

在整个手机操作系统里面就只有一个实例存在,并且这个实例是在他自己单独的任务栈里面,不会用默认的任务栈.
有道词典的快速取词
电话呼叫 InCallScreen
音乐播放器

Activity的Flags

上面提到可以在代码中通过设置Flag决定Avtivity的启动模式,不过Activity的Flag可是有很多种的,下面把与启动模式有关的Flag列出来:

FLAG_ACTIVITY_NEW_TASK

  • 以singleTask模式启动,但是不清除顶部的元素

FLAG_ACTIVITY_SINGLE_TOP

  • 以singleTop模式启动

FLAG_ACTIVITY_CLEAR_TOP

  • 将对应的activity上面的其他activity全部出栈
  • 与FLAG_ACTIVITY_NEW_TASK配合使用,被启动的Activity若已经存在实例,则直接调用该实例的onNewIntent
  • 若对应的Activity采用Standard模式,则会连同该实例以及以上的所有Activity一起出栈,再创建新的实例入栈
  • singleTask模式默认具有此Flag的效果

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  • 具有该标志的Activity不会出现在历史记录中。也就是在这个ActivityA中开启了一个新的ActivityB,当按下返回键的时候,并不是回到A中,而是回到A的上一个Activity中,如果没有上一个,则应用退出。
  • 等同于在XML中指定Activity的属性 android:excludeFromRecents=”true”
  • 这是一个”一次性”的Activity

空进程

一个任务栈中Activity被清空,则对应的进程就会成为空进程,当内存不够用时,就会被系统首先回收掉。