Activity的四种启动模式

Activity四种启动模式

这部分应该是最最基础的了,但是还是有很多细节需要把握,不只是表面的知识点。

  • 1 Activity的管理是采用任务栈的形式
  • 2 任务栈采用“后进先出”的栈结构
  • 3 每按一次Back键,就有一个Activity出栈
image.png
  • 标准模式(standard)
    每启动一次Activity,就会创建一个新的Activity实例并置于栈顶谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。也就是说在ActivityA中启动了ActivityB那么ActivityB就在ActivityA的栈中
image.png
  • 单例模式(singleInstance)
  1. 作为栈内复用模式(singleTask)的加强版
  2. 打开该Activity时,直接创建一个新的任务栈,并创建该Activity实例放入新栈中
  3. 一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例
  4. 使用场景:多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。使用场景如闹铃提醒,将闹铃提醒与闹铃设置分离。
    四种启动模式图解

image.png

四种启动模式的区别

  • 决定打开的任务栈
    standard、singleTop启动模式的Activity的目标任务栈,和收到Intent的发送者在同一个任务栈内。
    singleTask启动模式打开的任务栈由参数TaskAffinity决定。
    singleInstance启动模式总是新建任务栈,不会被启动到一个其他任务栈里。
  • 是否允许多个相同的Activity实例
    standard、singleTop启动模式中,同一个Activity可以被实例化多次,并且存在于不同的任务栈中,且一个任务栈可以包括同一个Activity的多个实例;
    singleTask、singleInstance启动模式则限制只生成一个实例。
  • 是否允许不同的Activity实例存在于同一个任务栈内
    singleInstance启动模式独占一个任务栈,其它Activity实例不能存在于该任务栈里。
    另外三种模式,则可以和其它Activity实例共存于一个任务栈。
  • 是否每次都生成新实例
    standard模式:每次都生成新实例。
    singleTop模式:若启动的Activity不在栈顶,则生成新实例;
    singleInstance模式:所在栈的唯一Activity实例,只会实例化一次,以后每次都被重用。
    singleTask模式:若启动的Activity不在栈内,则生成新实例;
    启动模式的设置
    启动模式有两种设置方式:
  • 在AndroidMainifest设置
  • 通过Intent设置标志位
    1.在AndroidMainifest中设置
image.png

2.通过Intent设置标志位

image.png

image.png

二者设置的区别

  • Intent设置方式比Manifest设置方式的优先级要高,即以前者为准
  • 限定范围不同
    Manifest设置方式无法设定FLAG_ACTIVITY_CLEAR_TOP标识;Intent设置方式无法设置单例模式(singleInstance)
    介绍一下任务栈:
    (1)程序打开时就创建了一个任务栈, 用于存储当前程序的activity,所有的activity属于一个任务栈。
    (2)一个任务栈包含了一个activity的集合,去有序的选择哪一个activity和用户进行交互:只有在任务栈栈顶的activity才可以跟用户进行交互。
    (3)任务栈可以移动到后台,并且保留了每一个activity的状态. 并且有序的给用户列出它们的任务,而且还不丢失它们状态信息。
    (4)退出应用程序时:当把所有的任务栈中所有的activity清除出栈时,任务栈会被销毁,程序退出。
    任务栈的缺点:
    (1)每开启一次页面都会在任务栈中添加一个Activity,而只有任务栈中的Activity全部清除出栈时,任务栈被销毁,程序才会退出,这样就造成了用户体验差,需要点击多次返回才可以把程序退出了。
    (2)每开启一次页面都会在任务栈中添加一个Activity还会造成数据冗余,重复数据太多,会导致内存溢出的问题(OOM)。
    为了解决任务栈的缺点,我们引入了启动模式。
    Standard
       默认模式 v,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。
      若我有一个Activity名为A1, 上面有一个按钮可跳转到A1。那么如果我点击按钮,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上…….
      点back键会依照栈顺序依次退出。
    singleTop
      可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
    例如:
      若我有两个Activity名为B1,B2,两个Activity内容功能完全相同,都有两个按钮可以跳到B1或者B2,唯一不同的是B1为standard,B2为singleTop。
      若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2,实际只调用了前一个的onNewIntent方法)
      若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。
    singleTask
       只有一个实例。在同一个应用程序中启动的它时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
       如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
    例如:
       若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,其中C2为singleTask模式,那么,无论我在这个程序中如何点击启动,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多个实例,但是C2只会存在一个,并且这三个Activity都在同一个task里面。但是C1->C2->C3->C2->C3->C1-C2,这样的操作过程实际应该是如下这样因为singleTask会把task中在其之上的其它Activity destory掉。
    操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2
    实际:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2
      若是别的应用程序打开C2,则会新启一个task
      如别的应用Other中有一个activity,taskId为200,从它打开C2,则C2的taskIdI不会为200,例如C2的taskId为201,那么再从C2打开C1、C3,则C1、C3的taskId仍为201。
    注意:如果此时你点击home,然后再打开Other,发现这时显示的肯定会是Other应用中的内容,而不会是我们应用中的C1 C2 C3中的其中一个。
    singleInstance
      只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。
    例如:
      加载该Activity时如果没有实例化,他会创建新的Task后,实例化入栈,如果已经存在,直接调用 onNewIntent,该Activity的Task中不允许启动其它的Activity,任何从该Activity启动的其他Activity都将被放到其他task中,先检查是否有本应用的task,没有的话就创建。
      程序有三个ActivityD1,D2,D3,三个Activity可互相启动,其中D2为singleInstance模式。那么程序从D1开始运行,假设D1的taskId为200,那么从D1启动D2时,D2会新启动一个task,即D2与D1不在一个task中运行。假设D2的taskId为201,再从D2启动D3时,D3的taskId为200,也就是说它被压到了D1启动的任务栈中。
    singleInstance附加解释:
       这种启动模式比较特殊,因为它会启用一个新的栈结构,将Activity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。
       我们修改MainActivity的launchMode=”standard”,SecondActivity的launchMode=”singleInstance”,由于涉及到了多个栈结构,我们需要在每个Activity中显示当前栈结构的id,所以我们为每个Activity添加如下代码:
    TextView textview=(TextView)findViewById(R.id.tv); textview.setText("current tesk id"+this.getTaskId());
image.png
image.png

  我们发现这两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下

image.png

   上半部分图我们看到从MainActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到MainActivity,这个时候系统会在原始栈结构中生成一个MainActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到MainActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。

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

推荐阅读更多精彩内容