你真的明白Task吗?

LauchMode

对于Activity的LauchMode想必大家都不陌生。

  • Standard(标准)
  • SingleTop(栈顶复用)
  • SingleTask(栈内复用)
  • SingleInstance(单例模式)

但是我们真的懂如何运用,或者这些Mode设计的原因是解决什么目的吗?概念总是很单薄,看的似懂非懂。所以我们需要通过场景去了解这些东西本质。才不会看了忘,忘了看,无限循环。

1、Standard

每次启动Activity都会创建一个新的实例,不管任务栈里面是否有。

注意:平时我们启动Activity都是在Activity里,但是当我们在Service或者Receiver中,我们调用的是Service和Receiver的Context,他们并不是Activity没有任务栈,那怎么办呢?添加FLAF_ACTIVITY_NEW_TASK标记位,那么它是否还新启动一个任务栈,还是沿用原来的呢?需要分情况分析,下边讲解FLAF_ACTIVITY_NEW_TASK会说明的。

2、SingleTop

位于任务栈栈顶的的Activity,再次启动的时候不需要重新创建。如果不在栈顶,那么就需要重新创建了。看名字就知道,只能在栈顶复用。

注意:我们重新复用的这个Activity的onCreate和onStart不会被系统调用,但是会调用onNewIntent这个回调,我们可以从这个方法里面获取data信息。比如getIntent()等等。

3、SingleTask

这个是重点也是难点,一定要注意这个。

栈内复用,只要Task任务栈里存在这个Activity,那么当重新启动这个Activity的时候就会复用,复用细节和SingleTop一致。默认具有clearTop作用。当Task任务栈里从底到顶分别是acitivty :ABCD,当B(LauchMode=SingleTask)再次启动的时候,他会进行复用,在复用的同时,会把它上面的Activity都清理掉,任务栈就变成了AB。

通过FLAF_ACTIVITY_NEW_TASK标志位启动的Activity会被赋值为SingleTask,并且会新建一个任务栈。

4、SingleInstance

单例模式,加强版的SingleTask,SingleTask有的他都有,而且比SingleTask还要霸道,具有此模式的Activity只能单独位于一个任务栈。当该Activity启动后,再次启动都是复用。

TaskAffinity

讲完四大启动模式,我们要讲taskAffinity,这是重点也是难点。

TaskAffinity可以翻译成 任务相关性,标志了一个Acitivty所需要的任务栈的名字。
TaskAffinity一般是和singleTask 或者allowTaskReparenting配对使用,在其他情况下也没什么作用,所以我们重点看这两个配对的使用。

1、TaskAffinity和singleTask

TaskAffinity是具有这个模式的activity的目前任务栈的名字。
待启动的Activity会运行在名字和TaskAffinity一样的任务栈中。
就是说当这个Activity(明确了TaskAffinity)是第一个的时候,会把这个任务栈命名成他TaskAffinity的名字。后续的未特殊处理的Activity都会进入这个栈。
当这个Activity(明确了TaskAffinity)不是第一个,他前面有一个栈而且里面有Activity,那么因为TaskAffinity不同(默认是包名)那么这个activity会新启一个任务栈命名为他的TaskAffinity,后续的Activity会进入他的任务栈。

2、TaskAffinity和allowTaskReparenting

举个例子:

如果A应用启动了B应用的界面(Activity) C,C的allowTaskReparenting=true,按Home键,回到主界面,然后我们在点击B应用的桌面图标打开B应用,我们发现,显示的并不是B的主Activity,而是C Activity,C的任务栈从A转移到了B。

分析:

因为A启动了C,所以C的任务栈在A,但是C是属于B的(记住这一点),因为C的TaskAffinity是和A任务栈的TaskAffinity是不同的,所以当B启动的时候,B会创建B任务栈,当C发现B的TaskAffinity和他的一样,然后就会从A任务栈中跑道B任务栈。

有意思的结论:

你捡了一条狗,好吃好喝的喂着,他也把这里当家了,但是有一天它的主人来了,他就屁颠屁颠跟着它的主人走了。

实验

当我们把这些结论写出来的时候,其实大多数人还是懵逼的,为什么呢?缺乏实际情景,还是不知道怎么应用?

我们就一一做实验,用数据和情景来学习这些知识。

顺序从上到下

1、Standard

A_acitivty (Standard)
B_activity (Standard)
C_activity (Standard)

image.png

返回栈 C -> B -> A

2、SingleTop

2、1
A_acitivty (Standard)
B_activity (Standard)
C_activity (Standard)
B_activity (SingleTop)


image.png

返回栈 B -> C -> B -> A

2、2
A_acitivty (Standard)
B_activity (Standard)
C_activity (SingleTop)
C_activity (SingleTop)

image.png

返回栈 C -> B -> A

我们发现C-> C 复用了C。且调用了onNewIntent方法。

3、SingleTask

3.1

A_acitivty (Standard)
B_activity (Standard)
C_activity (SingleTask)


image.png

返回栈 C -> B -> A
这个情景和SingleTop功能一样。

3.2

A_acitivty (SingleTask)
B_activity (Standard)
C_activity (Standard)
A_activity (SingleTask)


image.png

返回栈 A
把栈顶BC都清理了。

3.3

A_acitivty (Standard)
B_activity (Standard)
C_activity (Standard+FLAF_ACTIVITY_NEW_TASK)
C_activity (Standard)

blic void onClick(View v) {
                Intent intent = new Intent(B_Activity.this,C_Activity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
image.png

返回栈 C -> C -> B -> A

我们发现并没有出现我们所想的那样,还是在一个任务栈
然后我们换个做法

3.4

A_acitivty (Standard)
B_activity (Standard)
MyService(FLAF_ACTIVITY_NEW_TASK)
C_activity (Standard)

 @Override
    public void onCreate() {
        super.onCreate();
        Intent intent1 = new Intent(getApplicationContext(), C_Activity.class);
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplicationContext().startActivity(intent1);
    }
image.png

返回栈 C -> C -> B -> A

3.5

A_acitivty (Standard)
B_activity (Standard)
C_activity (SingleTask +FLAF_ACTIVITY_NEW_TASK)


image.png

怎么想换个任务栈这么难呢?书上都是骗人的吗?不是说好可以换的吗?
还好我们自己做了实验,不然你懂得~~呵呵哒。(书上并没有说错,只是没说清楚情况)
那怎么才能换一个任务栈呢?
这就用到了我们的重点TaskAffinity。

3.6

FLAG_ACTIVITY_NEW_TASK 和 TaskAffinity结合。
如果我们没有FLAG_ACTIVITY_NEW_TASK只设置TaskAffinity。 结果如下


image.png

当我们给Activity设置了TaskAffinity,并且设置了FLAG_ACTIVITY_NEW_TASK参数

  Intent intent = new Intent(B_Activity.this, C_Activity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);

 <activity android:name=".C_Activity"
           android:taskAffinity=".CCC"
            />
image.png

3.7

那么当SingleTask和TaskAffinity结合又会发生什么呢?


image.png

多么神奇的参数啊。所以TaskAffinity只会和四大模式中的SingleTast发生反应。当入栈的Activity是SingleTasK,而且有他的TaskAffinity,所以就会创建一个属于他的TaskAffinity任务栈,默认任务栈的名字是包名,所以新创建了一个任务栈。

3.8

那么当我们第一个Activity(SingleTasK)就设置TaskAffinity,后面的Activity还会进来吗?还是另起一个任务栈呢?


image.png

结论是 后面的Activity会进来这个任务栈。

FLAG_ACTIVITY_NEW_TASK

通过以上数据研究得出以下结论:
首先判断是否有与被启动的Activity相同的相关性任务栈,如果有,那么就不会重新启动一个任务栈。如果没有那么就需要重新启动一个任务栈了。

FLAG_ACTIVITY_NEW_TASK和SingleTask参数 是否开启新栈都与TastAffnity有关系,TastAffnity相同不会开启新栈,不同就会开启新栈。

4、SingleInstance

A_acitivty (Standard)
B_activity (Standard)
C_activity (SingleInstance)

image.png

返回栈C -> B -> A

SingleInstance很简单很暴力。那么如果我们第一个Activity是SingleInstance,后面的是Standard呢?


image.png

结论是SingleInstance很霸道,任务栈只能有他一个,如果有别的就新启一个任务栈。

5、TaskAffinity和allowTaskReparenting

5.1
A应用调用B应用的C(TaskAffinity,allowTaskReparenting=true)

B:MainActivity(Standard)
A:C_activity (Standard)
Home键
点击A应用的Icon,进去


image.png

我们发现,B应用打开启动主ActivityMainActivity,点击跳转A应用的C_activity。然后home键退出B应用,再点击启动A应用,但是A应用并没有打开他的主Activity(A_activity)而是又打开了C_activity。我们发现虽然都是同一个C_activity,但是任务栈变了。变成了B的任务栈,但是C_activity还是那个C_activity。

这就是著名结论:

你捡了一条狗,好吃好喝的喂着,他也把这里当家了,但是有一天它的主人来了,他就屁颠屁颠跟着它的主人走了。

6、其他情况

如果是A应用,启动了B应用的界面C

情况一:B应用的展示界面是C(Standard),按Home键返回桌面,然后A应用打开B应用的界面C,这个任务栈怎么说?


image.png

虽然跨应用了,但是还是一个任务栈。没什么区别

情况二:B应用的展示界面是C(SingleTop),按Home键返回桌面,然后A应用打开B应用的界面C,这个任务栈怎么说?


image.png

我们会发现,SingleTop跨应用的结论还是一直的的。

情况三:B应用的展示界面是C(SingleTask),按Home键返回桌面,然后A应用打开B应用的界面C,这个任务栈怎么说?


image.png

这个其实就触发了TaskAffinity,C的TaskAffinity默认是B应用的包名,A应用的TaskAffinity默认是A应用的包名,这里相当于TaskAffinity有了变化,根据SingleTask和TaskAffinity的性质,那么自然就会新起一个任务栈。

大家如果觉得有帮助的话,可以点个关注,告诉我大家想要深入探究哪些问题,希望看到哪方面的文章,我可以免费给你写专题文章。。或者私信沟通都可以。。。
希望大家多多支持。。你的一个关注,是我坚持的最大动力。。

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

推荐阅读更多精彩内容