Activity启动模式解析

主要内容

Activity是android的四大组件之一,可以说是我们android开发中最常用的技术之一。有关activity的知识点非常多,本文要介绍的是activity的四大启动模式。四大启动模式分别是standard(这是我们最常用的也是默认的一种启动方式)、singleTop、singleTask、singleInstance。接下来我们将分别介绍这四大启动模式以及他们的应用场景。


�任务和返回栈

在学习启动模式之前,我们需要先了解一下任务和返回栈的知识,应用通常包含多个Activity。每个 Activity 均应围绕用户可以执行的特定操作设计,并且能够启动其他 Activity。
任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即“返回栈”)中。
设备主屏幕是大多数任务的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷键)时,该应用的任务将出现在前台。 如果应用不存在任务(应用最近未曾使用),则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。
当前 Activity 启动另一个 Activity 时,该新 Activity 会被推送到堆栈顶部,成为焦点所在。 前一个 Activity 仍保留在堆栈中,但是处于停止状态。�这个保存Activity的堆栈就是返回栈。了解了任务以及返回栈以后,我们就可以来正式学习启动模式了。

standard

standard是系统默认的启动模式,系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。返回栈以“后进先出”对象结构运行,下图就是standard模式下返回栈的工作过程。


这里写图片描述

图 1. 显示任务中的每个新 Activity 如何向返回栈添加项目。 用户按“返回”按钮时,当前 Activity 随即被销毁,而前一个 Activity 恢复执行。
在没有特殊要求的大多数情况下,我们均使用这种默认的启动模式。

singleTop

如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例(官方文档的描述)。这句话的意思就是当一个Activity处于栈顶且启动模式被设置为singleTop时,当再次启动activity就会通过onNewIntent()来启动它,在栈顶不会创建新的实例。
例如在默认情况下返回栈中依次有A-B-C-D四个activity,如果D的启动模式为Standard,当再次启动D时,任务栈中就会变为A-B-C-D-D。但是如果D的启动模式为singleTop,则当再次启动D时,返回栈还是A-B-C-D。如果B的启动模式为singleTop,当再次启动B时,仍然会重新创建B的实例,返回栈变为A-B-C-D-B.


这里写图片描述

这里ABCD的启动模式均为standard,所以当D再次启动D时会重新创建D的实例,回退时的顺序为D-D-C-B-A.


这里写图片描述

这里将D的启动模式设置为singletop,所以当D再次启动D时由于此时位于栈顶的就是D所以不会产生D的实例了,回退时的顺序就是D-C-B-A
这里写图片描述

这里将B设置为了singletop,其他均为standard,点击D时启动了B,由于B并不在栈顶,所以重新创建了B实例,回退时的顺序就是B-D-C-B-A.

singleTask

这是四大启动模式中最难理解的一中了,系统创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。(这是官方文档上的描述,我觉得描述的太抽象很难理解)。
要想彻底理解singleTask这个启动模式,需要先理解一个taskAffinity。每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task(任务)。如果一个Activity没有显式的指明该 Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根 Activity的taskAffinity的值。
现在就可以来解释一下singleTask这个启动模式了。当一个activity的启动模式为singleTask,当要启动这个activity时,首先会寻找有没有和它taskAffinity相同的任务,如果没有,就会单独创建一个以这个activity的taskAffinity为taskAffinity的任务栈,activity进入到这个新创建的任务栈中;如果有这个任务栈,还会继续寻找在这个任务栈中有没有它的实例存在,如不存在,此activity放入栈顶,如存在,则将此activity上面的所有activity弹出栈外,activity位于此返回栈的栈顶,在此过程中并未创建新的activity实例。
例如,有一个taskAffinity为1的task中存在A-B-C-D四个activity实例,当有B的taskAffinity为1且启动模式为singleTask,此时启动B时并不会启动新的实例,taskAffinity为1的task会变为A-B。如一个Activit E的taskAffinity为2且启动模式为singleTask,则会产生一个新的taskAffinity为2的task,它的栈内只有一个E,而taskAffinity为1的task中亦然是A-B-C-D。


这里写图片描述

这里将B的启动模式设置为了singletask且taskAffinity未重新设置,当D启动B时,由于之前A-B-C-D这个返回栈中已经存在了B,所以B不会创建新的实例而是将C、D挤出返回栈,B通过onNewIntent()至于栈顶,所以回退时的顺序就是B-A.

singleInstance

这种启动模式也比较好理解,当一个activity以这个启动模式启动时,都会为它单独创建一个任务栈,且这个任务栈中有且只能有一个它。

NOTE

无论 Activity 是在新任务中启动,还是在与启动 Activity 相同的任务中启动,用户按“返回”按钮始终会转到前一个 Activity。 但是,如果启动指定 singleTask 启动模式的 Activity,则当某后台任务中存在该 Activity 的实例时,整个任务都会转移到前台。此时,返回栈包括上移到堆栈顶部的任务中的所有 Activity。 下图显示了这种情况。


这里写图片描述

图 :显示如何将启动模式为“singleTask”的 Activity 添加到返回栈。 如果 Activity 已经是某个拥有自己的返回栈的后台任务的一部分,则整个返回栈也会上移到当前任务的顶部。


这里写图片描述

如图,首先打开了bootmode1,点击了AA,假设产生了一个taskAffinity为bootmode1返回栈,其结构是AA-BB,点击home键将其放入后台后打开BootMode,依次点击A-B-C-D,其中D按钮的点击效果是使用隐式启动打开bootmode1里的BB,然后一直按返回键,我们可以看到返回的顺序为BB-AA-D-C-B-A,符合上面的结论.

intent的标记

FLAG_ACTIVITY_NEW_TASK
在新任务中启动 Activity。如果已为正在启动的 Activity 运行任务,则该任务会转到前台并恢复其最后状态,同时 Activity 会在 onNewIntent() 中收到新 Intent。这种启动标记的作用相当于启动模式中的singleTask。
FLAG_ACTIVITY_SINGLE_TOP
如果正在启动的 Activity 是当前 Activity(位于返回栈的顶部),则 现有实例会接收对 onNewIntent() 的调用,而不是创建 Activity 的新实例。这种启动标记的作用相当于启动模式中的singleTop。
FLAG_ACTIVITY_CLEAR_TOP
如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并通过 onNewIntent() 将此 Intent 传递给 Activity 已恢复的实例(现在位于顶部),而不是启动该 Activity 的新实例。而这个标记通常与FLAG_ACTIVITY_NEW_TASK在一起结合使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容