文章主要介绍了
Android 的为什么需要启动模式?
Android 的启动模式
Android 的启动模式使用场景
Android 的启动模式的使用
Android 中的 Activity 启动模式是什么?
Activity 为什么需要 启动模式?
我们知道在默认情况下,当我们多次启动同一个 Activity 的时候,系统会创建多个实例并把他们一一放到任务栈中。这里的栈是一种后进先出的结构,所以当我们按下 back 键时,会将最后加入的 Activity 先移出栈。
后进先出: 指的是最后进入栈内的,在移出时是最先移除的。如下:
Android 中为了在多次启动同意额 Activity 时,不重复创建多个实例,所以他提供了启动模式来修改系统的显示行为。
目前有四种启动模式:standard
,singleTop
,singleTask
,singleInstance
。那么他们表示什么含义呢?
standard (标准模式-也就是默认模式)
每次启动 Activity
时都会创建一个Activity
实例,不管这个实例是否已经存在。它都会被放入任务栈中。出现的情景大概如下图所示:
singleTop (栈顶复用模式)
- 如果新
Activity
已经位于任务栈的栈顶,那么该Actvity
将不会被重新创建。同时它的onNewIntent()
方法会被回调,通过此方法我们可以取出当前请求的信息。 - 如果新
Activity
不位于任务栈的栈顶,那么该Actvity
还是会被重新创建。
简单图示如下:
singleTask(栈内复用模式)
这是一种单实例模式
,在这种模式下,只要Activity
在一个栈中存在,那么多次启动此Activity
都不会重新创建实例。和singleTop
一样会回调onNewIntent()
方法,通过此方法我们可以取出当前请求的信息。
简单图示如下:
singleInstance
单实例模式,这是一种加强的singleTask
模式,他除了具有singleTask
模式的所有特性之外,而且具有此种模式的Activity
只能单独的位于一个任务栈中。
简单图示如下:
目前在项目中的使用场景?
- 首页使用
SingleTask
模式,不使用SingleInstance
模式。
原因是:
(1)防止生成重复页面。
因为首页可能不一定从点击Iocn
启动才进入,可能是从广播
或者分享的网页链接点击后进入。
(2)在使用overridePendingTransition
启动首页页面时,如果使用SingleInstance
模式会出现一段时间的白屏,推测原因可能是新建了新的任务栈导致
(还未测试,忘知道的朋友告知原因)
如何使用?
第一种方式:
在AndroidManifest.xml
中找到要设置的activity
,然后添加launchMode属性
,如下:
<activity
android:name=".launch_model.AActivity"
android:launchMode="standard">
第二种方式:
在 Java
代码中设置flag
标记位,通过设置的标记位可以设定Activity
的启动模式,但是这种方式不能为Activity
设置SingleInstance
模式。
常见的和启动模式相关的标记位如下:
- FLAG_ACTIVITY_NEW_TASK
该标志位的作用是为 Activity
指定 singleTask
启动模式,和在AndroidManifest.xml
设置的launchMode="singleTask"
的作用是一样的。
Intent intent = new Intent(MainActivity.this, AActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
- FLAG_ACTIVITY_SINGLE_TOP
该标志位的作用是为 Activity
指定 singleTask
启动模式,和在AndroidManifest.xml
设置的launchMode="singleTop"
的作用是一样的。
该标志位的作用是为 Activity
指定 singleTop
启动模式,和在AndroidManifest.xml
设置的launchMode="singleTop"
的作用是一样的。
Intent intent = new Intent(MainActivity.this, AActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
- FLAG_ACTIVITY_CLEAR_TOP
该标志位的作用是,当标记了该标志位的Activity
启动时,在同一个任务栈中所有位于它上面的Activity
都要出栈。这个标记位一般会和singleTak
启动模式一起出现。
如果被启动的Activity
的启动模式是standard
模式,那么它连同它之上的Activity
都要出栈,系统会重新创建新的实例
Intent intent = new Intent(MainActivity.this, AActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有这个标记的Activity
不会出现在历史Activity
的列表中,
Intent intent = new Intent(MainActivity.this, AActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
它等同于在AndroidManifest.xml
设置的excludeFromRecents="true"
的作用是一样的。
<activity android:name=".launch_model.AActivity"
android:excludeFromRecents="true">
两种方式的使用区别:
- 第二种方式的优先级高于第一种方式,如果两种方式都存在,以第二种方式为准。
- 二者的限定范围不同。第一种方式无法直接设置
FLAG_ACTIVITY_CLEAR_TOP
标识;而第二种方式无法为Activity
指定SingleInstance
模式
参考
Android 开发艺术探索