一. 前提知识
1.1. 任务栈知识
二. Activity启动模式的学习
2.1 standard
2.2 singleTop
2.3.singleTask
2.4.singleInstance
引言:
Activity作为四大组件之一,也可以说Activity是其中最重要的一个组件,其负责调节APP的视图,和用户交互功能,可以说非常重要,当我们深入了解了Activity的生命周期之后,就可以写出更流畅的程序。
Activity****的启动模式:
我们的Activity会根据自身不同的启动模式,自身的生命周期方法会进行不同的调用。我们应该根据特定的需求,为每个Activity指定恰当的启动模式。我们可以在A你的肉i的Mainfest.xml中通过给 <activity> 标签指定android:launchMode属性来选择启动模式。
一**.**前提知识
1.1****任务栈知识
我们先来了解一下什么是任务栈:说白了,任务栈就是用来存放任务的,每个应用都有一个任务栈,来存放不同的任务。
看图了解下:
图 1 :任务栈
出现的顺序就是根据我们上面的数字顺序。
二**.Activity****启动模式的学习**
2.1 standard**(标准模式)**
standard作为Activity的默认启动模式,在不进行显示指定的情况下,所有Activity都会自动使用这种启动模式。到现在为止,我们写过的所有Activity都是使用的standard模式。我们知道Android是使用返回栈来管理Activity的,在standard模式中,每当启动一个新的Activity,其就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的Activity,系统不会在意这个Activity是否已经在返回栈中存在,每次启动都会创建一个该Activity的新实例。
我们现在通过代码实践体会standard模式,修改项目,首先来看代码:
1.默认情况下都是Standard模式
2.一个叠加一个,符合先进后出的规律
先看一下配置形式的代码:
<activity android:name=".standard.StandardActivity"
android:launchMode="standard" >
接下来,我们解析一下这段代码:
- android:name 属性
这是 Activity 的完全限定类名。
在你的例子中, StandardActivity 位于 com.example.holiday.standard 包中。
举个例子,如果我们的的应用包名是 com.example.holiday ,那么完整的类名应该是 com.example.holiday.standard.StandardActivity 。
- android:launchMode 属性
launchMode 定义了 Activity 的启动模式,决定了 Activity 在任务栈中的行为。
在我们的例子中, launchMode 被设置为 "standard" ,这是默认的启动模式。
- 同样,因为standard 是默认的模式,所以android:launchMode 可以不进行声明,因为默认就
是standard
我们简单看图举个例:
![](https://i-blog.csdnimg.cn/direct/b173f989e41f4d2bbbdf6729b9b3b38a.png)
图2:standard 模式,添加Activity页面时的栈变化
2.2 singleTop**(栈顶复用模式)**
这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。
当跳到一个SingleTop模式的Activity时:
1.判断当前的任务栈的栈顶是否是该Activity
2.如果栈顶不是,则新建一个,并正常入栈3.如果栈顶是,直接复用栈顶的Activity,不新建Activity
配置一下代码:
<activity android:name=".singletop.SingleTopActivity"
android:launchMode="singleTop">
接下来我们看图理解Acitivty的栈顶复用模式的过程图:
图3:起初的Activity的任务栈
![](https://i-blog.csdnimg.cn/direct/1040893a9c064cf39594c50775f40702.png)
图4:添加Activity页面时的栈的变化
![](https://i-blog.csdnimg.cn/direct/ec7550223b384821835f1904752afdd3.png)
图5:Activity0退回栈的变化
图 6 : Activity6 栈的变化
singleTop模式分3****种情况
1.当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
2.当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
3.当前栈中不存在该Activity的实例时,其行为同standard启动模式
standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task**,即使你**
指定了taskAffinity属性。
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。
1.这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字
为应用的包名
2.我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
3.一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
4.在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个
任务
5.为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task
2.3singleTask**(栈内复用模式)**
使用singleTop可以很好的解决重复创建栈顶Activity的问题,但是我们知道如果该Activity并没有处于栈顶位置,还有可能会创建多个Activity实例的。那么有没有办法可以让某个Activity在整个应用程序的上下文只存在一个实例呢?这就要借用singleTask模式来实现了。当Activity启动模式指定为singleTask时,每次启动Activity,系统首先会在返回栈中检查是否存在Activity的实例,如果发现则直接使用该实例;并把这个Activity之上的所有其他的Activity统统出栈,如果没有就会创建一个新的。
配置一下代码:
<activity android:name=".singletask.SingleTaskActivity"
android:launchMode="singleTask">
![](https://i-blog.csdnimg.cn/direct/6775eeab63f04cdeaa719d472fa4c838.png)
图7:起初的Activity的任务栈
![](https://i-blog.csdnimg.cn/direct/a9e49fb8482f446ca77a6e4d7757a37e.png)
图8:singleTask的Activity的任务栈启动模式
2.4singleInstance**(单实例模式)**
singleInstance模式算是四种启动模式里最复杂也是最特殊的的一个了,我们需要多花时间来理解这个模式。不同于以上3种启动模式,指定为singleIeInstance模式的Activity会启用一个新的返回栈来管理这个Activity(其实如果 singleTask 模式指定了不同的taskAffinity,也会启动一个新的返回栈)。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个Activity是允许其他程序调用的,如果想实现其他程序和我们的程序可以共享这个Activity的实例,应该如何实现呢?使用前面3种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个Activity不同的返回栈中入栈时必然创建了新的实例。而使用singleinstance 模式就可以解决这个问题,在这种模式下,会有一个单独的返回栈来管理这个 Acivity,不管是哪个应用程序来访问这个Activity,都共用同一个返回栈,也就解决了共享Aciviy实例的问题。
配置一下代码:
Activity1是SiglelnInstarce模式
<activity android:name=".singleInstance.SingleleInstanceActivity"
android:launchMode="singleInstance">
![](https://i-blog.csdnimg.cn/direct/5c9117ec596c4e248477a62d08d1b580.png)
图10:启动创建Activity0
图 11 :启动 Activity1
图12:Activity1启动Activity2
![](https://i-blog.csdnimg.cn/direct/5d9f0cb1fb45451b83a4ab5cb82ee5bd.png)
图13:Activity2启动Activity3