Activity_启动模式

在正式对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的位置上。

欢迎关注我Github : @ 我的github

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值