Activity的启动模式

Activity为什么需要启动模式?在默认情况下,当多次去请求同一个Activity时候,系统会创建多个实例并把它一一放入到任务栈中,当按下back键的时候,Activity会一一回退。因为“栈”是一种后进先出的结构。当Activity默认启动时候,系统会重复创建多个实例,为避免这种情况,所以Android提供了四种启动模式来修改系统的默认启动模式:standard,singleTop,singleTask,singleInstance。

1.standard,标准的启动模式,即系统的默认启动模式,每次启动都会创建一个实例,不管实例是否存在,创建的实例生命周期符合Activity正常的生命周期。典型的多实例体现,一个任务栈中可以有多个实例,每个实例可以有不同的任务栈。
举例:Activity A 启动了ActivityB(standard模式),那么B会进入到A栈中。
注:当用ApplicationContext去启动standard的时候,会抛出异常:

Paste_Image.png

这是由于ApplicationContex没有所谓的任务栈,此时应给待启动Activity添加FLAG_ACTIVITY_NEW_TASK标记位,这样Activity启动会为它创建一个新的任务栈,实际上采用了singleTask模式启动。

2.single Top:栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈栈顶,那么Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法可以取出当前请求信息。

注:此模式下的Activity的onCreate,onStart不会被调用。如果新Activity不在栈顶,那么仍会重新创建。

举例:栈内有ActivityA,B,C,D。A位于栈底,D位与栈顶。如果D启动模式为standard,那么为ABCDD。如果D启动模式为singleTop,那么为ABCD。

3.singleTask,栈内复用模式。这是一种单例模式,在此模式下,只要Activity在一个栈中存在,那么多次启动Activity都不会创建实例,和singleTop相同,系统也会回调onNewIntent。

举例:ActivityA启动模式为singleTask,系统会寻找是否存在A想要的任务栈,如果不存在就重新创建一个栈,然后创建A的实例并放入栈中。如果存在A所需的任务栈,则会去检查栈中是否存在A的实例,如果存在,系统调用A的onNewIntent,并把A调到栈顶。如果不存在实例,就创建实例并压入栈中。
具体情况举例:

(1)任务栈S1有ABC,D以singleTask模式请求启动后,D所需的任务栈为S2,S2不存在,系统会创建S2任务栈和D实例并入栈S2。
(2)D所需的任务栈为S1,那么系统检查S1里是否存在D实例,如果不存在,创建D实例并入栈S1。
(3)与(2)同,但是D实例存在,调用D的onNewIntent,并且此时D位于S1任务栈的栈顶。同时由于singleTask默认具有clearTop的效果,D上面的Activity会全部出栈,如ADBC会变成AD。

4.singleInstance:单实例模式。singleTask模式的加强版,不同的是,此模式的Activity只能单独位于一个任务栈中。

举例:
Activity A是singleInstance启动模式,那么A启动后,系统会为A单独创建一个新的任务栈,A独自在这个新任务栈中,且由于栈内复用特性,后续请求都不会重新创建A,除非这个新任务栈被系统销毁。

思考问题:假设有两个任务栈,S1,S2。S1是前台任务栈AB,S2是后台任务栈CD。CD启动模式均为singleTask,那么现在请求启动C和请求启动D有什么区别?
个人理解:如果请求D,那么后台任务切换到前台,那么后退列表变为ABCD,如果请求C,那么C会把D给清除掉(singleTask的clearTop的效果),那么后退列表就变成ABC。

什么是singleTask的所需任务栈呢?
即一个参数:Taskfinity(任务相关性),此参数标识了一个Activity所需要任务栈的名字,默认情况下,所有Activity所需任务栈都是包名。Activity也可以单独指定Taskfinity属性,但是该属性必须与包名不同,否则指定无意义。Taskfinity必须和singleTask启动模式或者和allowTaskReparenting属性配对使用,其他情况也无意义。任务栈分前台任务栈和后台任务栈。

当Taskfinity和singleTask配对使用,它具有当前该模式Activity目前任务栈的名字,待启动的Activity会运行在名字和Taskfinity相同的任务栈中。

当Taskfinity和allowTaskReparenting结合使用,会产生特殊情况。当应用A启动了B的某个ActivityC后,如果C的allowTaskReparenting属性为true,那么当应用B启动后,C会直接从应用A移动到应用B的任务栈中。通俗来说,此时应用B启动后并不会启动B的主Activity,而是重新显示在A里已启动的C(此时C从A任务栈转移到到B任务栈,由于是A启动C,C只能在A任务栈,但是C又属于B,而Taskfinity值又肯定不能和A相同(包名不允许相同),所以当B启动后又会创建新任务栈,这时系统会发现C的任务栈已经被创建了,所以C会移动到B任务栈)。

至此,我也明白了工作中调用第三方app后(如地图导航)返回后仍是自己APP的界面以及重新进入第三方app直接显示之前调用界面的原因。

指定Activity的启动模式有两种,一种是通过AndroidMenifest为Activity指定启动模式:

Paste_Image.png

另一种通过intent中设置标志位来指定启动模式:

Paste_Image.png

二者区别:
intent指定优先级高于AndroidMenifest指定,两者若同时存在,以intent为准。
限定范围不同:AndroidMenifest指定无法直接设定FLAG_ACTIVITY_CLEAR_TOP标识,而intent无法为Activity指定singleInstance模式。

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

推荐阅读更多精彩内容