您的位置:首页 > 移动开发 > Android开发

android学习笔记——关于Activity的启动模式(更新)

2016-04-21 18:01 375 查看
在正式对Activity的启动模式讲解之前先了解一个概念,关于任务。
用户为了完成某个功能而执行的一系列操作形成了一个Activity序列。这个序列在Activity中称之为任务,它是从用户体验的角度出发,把一组相关的Activity(这些Activity可以来自不同的应用程序)组织在一起而抽象出来的概念。因此,任务包含一个按照用户交互顺序排序的Activity集合,任务可以把每个Activity按照用户执行顺序放到后台,并且保持状态且不丢失工作。
当一个Activity启动时,任务也随之启动的话,那么这个Activity就是根Activity。android系统内部一旦有任务,那么按返回键就可以回到上一个Activity。Activity栈可以是多个任务的组成部分。
任务中的所有Activity是作为一个整体进行移动的,这就是任务的聚合性。整个任务可以(即整个Activity堆栈)可以移动到前台或退至后台。

然后我来介绍一下Activity的加载模式
定义加载模式的方法有如下两种

在AndroidManifest中声明
使用Intent标志

AndroidManifest中声明它包括四种加载模式:
standard、singleTop、singleTask和singleInstance
(1)standard模式
standard模式是默认的模式。每次访问都实例化新的Activity,即系统在启动Activity的任务中创建一个新的Activity实例,并且把Intent传送路径指向他。该Activity可以被实例化多次,各个实例可以属于不同的任务,一个任务中也可以存在多个实例。
(2)singleTop模式
每次访问时,首先看栈顶元素的目标对象,如果是当前Activity实例,则返回,不在实例化该Activity,否则,重新实例化新的Activity。即如果Activity的一个实例已经存在于当前任务的栈顶,该系统就会使用onNewIntent()方法通过Intent传递给已有的实例,而不是创建一个新的实例。Activity可以被实例化多次,各个实例可以属于不同的任务,一个任务中可以存在多个实例。例如,假设任务的Activity栈中包含了根Activity
A和 Activity B、C、D(顺序是A-B-C-D),D在栈顶。这时候传过来的是启动D的Intent,如果D的启动模式是默认的“standard”,则会启动一个新的实例,栈的内容就会变为 A-B-C-D-D。但是,如果D的启动模式是“singleTop”,则已有的D的实例会通过onNewIntent()接收这个Intent,由于该实例位于栈顶——栈中内容仍然维持A-B-C-D不变。当然,如果Intent是要启动B的,则B的一个新实例还是会加入栈中,即使B的启动模式是“singleTop”。也就是说,唯有当被启动的Activity是位于栈顶,且启动模式是“singleTop”的该模式会生效。
(3)singleTask模式
singleTask模式和后面的singleInstance 模式都是只创建一个实例,保证Activity只实例化一次,由此所开启的Activity和当前Activity位于同一任务中。系统会创建一个新的任务,并把Activity实例作为根放入其中。但是,如果Activity已经在其他任务中存在实例,则系统会通过调用其实例的onNewIntent()方法把Intent传给已有实例,而不是再创建一个新实例。
singleTask模式启动Activity的特点:
1. 设置了“singleTask”启动模式的Activity在启动时,首先在系统中查找属性值affinity等于它的任务是否存在,如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。
2. 如果设置了“singleTask” 启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。
在启动了一个启动模式设为 singleTask 的Activity,且有一个后台任务中已存在实例时,这个后台任务就会整个转到前台。这是,当前的Activity栈就包含了这个转入前台的Task中所有的Activity,位置是在栈顶。
如下图所示

(4)singleInstance模式
singleInstance模式下的Activity单独在一个任务栈中,这个栈只有一个Activity。除了系统不会把其他Activity放入当前实例所在的Task之外,其他均与singleTask模式相同,Activity总是它所在Task的唯一成员;它所启动的任何Activity都会放入其他Task中。
例如,Android的浏览器应用就把Web浏览器Activity声明为总是在它自己独立的任务中打开——把Activity设为singleTask模式。这意味着,如果应用提交Intent来打开Android的浏览器,则其Activity不会被放入应用所在的任务中。取而代之的是,或是为浏览器启动一个新的任务,或是浏览器已经在后台运行,只要把任务重新调入前台来处理新Intent即可。

使用Intent标志
在启动Activity时,可以通过Intent.setFlags()方法在传给startActivity()的Intent中包含相应标识,用于修改Activity与任务的默认关系。这个标识可以修改的默认模式如下:
(1)FLAG_ACTIVITY_NEW_TASK
在默认情况下,一个新Activity被另外一个调用了startActivity()方法的Activity载入了任务之重,并压入了调用者所在的堆栈。然而,如果传递给startActivity()的Intent对象包含了FLAG_ACTIVITY_NEW_TASK标记,系统会为该新Activity有着同样affinity属性值得任务,则Activity会载入到那个任务之中。如果没有,则启用新任务。
这个模式与前面所描述的“singleTask”加载模式相同。

(2)FLAG_ACTIVITY_SINGLE_TOP
如果要启动的Activity就是当前Activity(位于栈顶),则已存在的实例将接收到一个onNewIntent()调用,而不是创建一个Activity的新实例。这个模式与之前描述的“singleTop”启动模式相同。

(3)FLAG_ACTIVITY_CLEAR_TOP
如果目标任务的堆栈中已经存在一个能够响应此Intent的Activity类型的实例,则这个实例之上的所有Activity都将被清理,以使他位于栈顶的顶部来对那个Intent做出响应(通过onNewIntent()传入Intent并恢复Activity)。如果此时指定的Activity的启动模式是“standard”,则它本身也会从堆栈中移除,并启动一个新的实例来处理到来的Intent。
FLAG_ACTIVITY_CLEAR_TOP经常与FLAG_ACTIVITY_NEW_TASK结合在一起使用。这些表示定位在其他任务中已存在的Activity中,并再将其放入可以响应Intent的位置上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: