LaunchMode启动模式终结篇

我们在最开始学习Android的时候 就老是听到四个启动模式 面试的时候也是经常被问到四种启动模式是什么 但是却很少深入的真正的了解过 直到今天看到了扔物线的视频 我会了

因为该文是纯文字 所以有些枯燥 但是相信我 仔细读完 写一个Demo 你一定会有收获!!!

App切换

我们首先需要明确一个知识点 Activity是一个可以跨进程跨应用的组件 然后我们根据四种不同的启动模式 慢慢分析理解一下

Task

Task是用于存放Activity的
每个Task都有一个TaskAffinity 默认会取第一个进栈Actity的TaskAffinity
而Activity默认会取Application的TaskAffinity

Standard

比如说 我们在App A里面 加载了App B的Activity(Standard) 那么这个Activity会直接放进App A的Task里 而不会对B有什么影响

SingleTask

先总结一下 SingleTask 具有特性是Activity对应的Task内只能有一个当前Activity实例

举个例子 当我们从微信里发送一个手机号给我们的好友 然后长按这条消息 点击拨打
我们观察一下跳转动画 发现并不是Activity之间的跳转动画 而是App之间的跳转动画

其实上面这个操作流程如下:

  1. 判断拨打电话Activity(后面简称CallActivity) 是否存在
    如果存在则直接将CallActivity的Task压入wechatTask中 并将CallActivity之上的所有Activity出栈 并且不会创建CallActivity的OnCreate方法 取代会调用onNewIntent方法 并且会触发ClearTop的效果
  2. 如果不存在 则新建CallActivity 然后创建对应CallTask 并放入CallTask
  3. 将CallTask压入WeChatTask
  4. 所以我们点击返回按钮 会发现先回退CallTask里面的Activity 然后再退到WeChat的Task

大家可以先使用 然后再对比文章阅读 直接看可能没有动画来的直观

但是 我们在上面的第三步完成之后 这时候先不按返回键 而是按Home键或者菜单键 然后再点击CallActivity 我们会发现 一直点击返回按钮 会回到桌面 而不是回到WeChat的Task了

这是因为系统当回到桌面时 会将各Task进行分离

系统虽然声明为SingleTask 其实是对Activity的修饰 保证了全局只有一个这个Activity实例

TaskReparting

这个实现的效果和SingleTask差不多 举个例子 当我们从CallTask启动EmailActivity(TaskReparting = true) 然后回到桌面 再进去CallTask 会发现EmailActivity已经消失 打开邮件应用 EmailActivity会防止在EmailTask最顶部 这就是TaskReparting 当TaskA使用的时候 会存在于TaskA中 当不使用时 会回到自身的Task中

但是看了扔物线的视频 指出了TaskReparting在Andorid 9.0和10.0是存在Bug的 使用这个属性的同学 请做好测试

SingleInstance

SingleInstance 和SingleTask有点相似 SingleTask强调一个Activity只能在这个Task里出现一个实例 而SingleInstance更为霸道 一个activity在Task里只能出现一次 并且这个Task里只能有这个Activity

SingleInstance和SingleTask在实际的操作中区别如下

  • 当我们的应用分别启动一个SingleInstanceActivty和SingleTaskActivity 当我们点击返回时

    • SingleInstanceActivty会直接返回到当前App 因为SingleInstance中的Task只能存在一个Activity
    • 而SingleTaskActivity会现在SingleTask进行回退 回退完成才会切换到当前应用Task
  • 第二个区别就是 分别启动一个SingleInstanceActivty和SingleTaskActivity之后 我们点击Home键 然后分别启动SingleInstanceActivty和SingleTaskActivity对应的App

    • SingleTask App会看到这个Activity依然在栈顶
    • 而SingleInstanceActivty会发现在任务列表已经不见了 其实并不是被杀死了 只是SingleInstanceTask被切换到后台了

总结一下 感觉SingleTask强调唯一性 而SingleInstance更强调独占性

TaskAffinity

TaskAffinity我感觉是最绕的一个 所以下面会举例来说明

先解释一下TaskAffinity 我们上面讲过 每个Activity默认都会取Application的TaskAffinity 而Application默认会取包名 所以我们不修改Activity的TaskAffinity 那么Activity的TaskAffinity默认就是包名

下面我们分别对各种情况作出说明


ActivityA对应的TaskAffinity为Affinity_A launchMode为Standard

ActivityB对应的TaskAffinity为Affinity_B launchMode为Standard

ActivityC对应的TaskAffinity为Affinity_C launchMode为Standard

当我们点击App图标 启动ActivityA时 会创建Task, Task的TaskAffinity会是Affinity_A 然后再启动ActivityB会不会检查Affinity_B 而是直接入栈


ActivityA对应的TaskAffinity为Affinity_A launchMode为Standard

ActivityB对应的TaskAffinity为Affinity_B launchMode为SingleTask

ActivityC对应的TaskAffinity为Affinity_C launchMode为Standard

当我们点击App图标 启动ActivityA时 会创建Task, Task的TaskAffinity会是Affinity_A 然后再启动ActivityB 因为ActivityB的启动模式为SingleTask 所以会判断ActivityB的TaskAffinity
分为以下两种情况

  • TaskAffinity为Affinity_A 因为TaskAffinity一样 所以会直接将ActivityB入栈

  • TaskAffinity为Affinity_B 因为TaskAffinity不一样 所以会创建TaskB 并且将Activity_B入栈(Task_B的TaskAffinity为AffinityB)

然后再启动C 因为我们之前说过 因为C的launchMode为Standard 所以不会检查Activity_C的任务栈 直接入栈


ActivityA对应的TaskAffinity为Affinity_A launchMode为Standard

ActivityB对应的TaskAffinity为Affinity_B launchMode为SingleInstance

ActivityC对应的TaskAffinity为Affinity_C或者Affinity_A launchMode为Standard

当我们点击App图标 启动ActivityA时 会创建Task, Task的TaskAffinity会是Affinity_A 然后再启动ActivityB 因为ActivityB的启动模式为SingleInstance 所以会创建一个新的Task(AffinityB) 并且独占当前Task 然后创建C的时候
需要分为以下两种情况

  • Affinity_A 因为SingleInstance的缘故 所以没办法进入TaskB 但是Affinity_A已经创建 所以会将Affinity_A切换到前台 并且将ActivityC压入TaskA

  • Affinity_C 因为SingleInstance的缘故 所以没办法进入TaskB 并且当前任务栈是不存在的 所以这时候相当于和我们在桌面点击App图标一样 会创建一个新的Task(Affinity_C)

SingleTop

和Standard基本一样 启动时不考虑TaskAffinity 区别是启动时 如果当前Activity已经存在栈顶 那么不会调用onCreate方法 而是会调用onNewIntent方法

总结

Standard和SingleTop 更多用于App内部应用开发
SingleInstance 用于开放给其他App使用
SingleTask 内部交互和外部交互都用的上

大家还有什么不明白和不理解的 欢迎留言交流

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