看了很多关于Task的介绍之后,自己脑子里仍旧对Task 和 BackStack 表示很懵逼
我自己整理了一下 自己对Task 和返回栈的认识,结合进程的概念减少认知上的误区。
首先我们知道,每个组件都是在自己独立的application 环境下运行的,即每个组件都是在 这个application 的进程中进行的。那么当我们通过应用A调用了应用B的组件,的情况是这样的,系统开启了 应用B的Application,该组件运行在应用B的进程中。这里我想问,Task又是个什么东西呢,原来Task 是 用来管理 组件的,如何管理组件?他是站在用户的角度去管理组件,看到这里我已经懵逼了。什么叫站在用户的角度去管理组件,下面是一个例子
我们在自己的应用中,去打开系统的摄像头,按照上面的说法,系统摄像头应用application 已经启动了,即摄像头应用的进程已经开启。这时候我们看任务选择器去看可以启动的应用,发现只有我们自己的应用,没有摄像头应用。这就是Android对于Task的设计原因,他按照用户的行为习惯,把从我们自己应用打开摄像头默认为 这个摄像头是我们应用的一部分,因此对于用户而言没有打开第二个应用的意思。
理解了Task的设计原理,我们理解一下Task 是什么,Task 是 执行一定作业时与用户交互的一系列Activity。即我们要把Task 作为 一种整体的概念去理解,它是一系列的Activity的合体。那返回栈又是什么鬼,返回栈介绍了Task中的这些Activity 在堆栈中的存在形式。(返回栈:遵循先进先出原则)
这时候我就有一个问题,我打开的摄像头的Activity 是放在哪个Task,毫无疑问是我自己应用创建的 Task。
Task 是一个整体,有两个状态,一个是显示,一个是在后台。有什么特点,当task移动到后台,这个task所包含的所有Activity都会停止(stop),返回栈是保持不变的,保留了进入后台之前的状态(有几个Activity 保存几个activity)。当恢复到主屏幕时,位于堆栈栈顶的Activity就会恢复了。(可以自己科普一下如何保存Activity状态 —— onsaveInstanceState)
有没有特殊情况?还是有的,如果后台有多个Task,系统有可能会把Task中除了根Activity以外的Activity销毁,什么是根Activity(也就是应用的入口Activity)。
这都是系统的默认情况。
发现还有很多启动模式,还有很多关联,我当时就不理解了。为什么需要这些,默认情况还不够满足你的吗
果然还是有特殊情况的,我们举个例子,我们需要打开一个开销比较大的Activity(例如浏览器),它会被加入到我们应用中的Task当中,貌似没什么问题,如果很很多这样的程序,系统就有点吃不消了。每个应用的Task 都存在这样开销大的 而且是同一个 Activity,显然是不合理的,为毛不能独立一下,让这个Activity在自己的Task中,别的应用可以分享啊是不是,这样就不会有更多的Activity了。这就需要这个Activity位于一个Task中,有且只有栈顶,这样就只有一个Activity,没有更多了。
扯了那么多这个和launchMode 有什么关联
这里有一个 启动模式 SingleInstance 啥意思,为了就是解决上面所遇到的问题。让开销比较大的Activity 独立开来,怎么独立,它会自己创建一个新的Task,有什么特点,整个Android系统就这一个,没有更多了,这个Task 有什么特点,这个Task只保存这一个Activity,没有更多了。
为毛还有三个LaunchMode
其他三个是针对Activity在一个Task中的存在形式,
为毛是三个:1.标准情况:每次我们startActivity 都会 创建一个新的Activity实例,也就是说如果可以的话一个Activity实例可以出现多个在一个Task中(也可以存在于不 同Task中)
2.SingeTop : 这个是干嘛用的?每次Start一个Activity ,先看看 这个Activity是不是位于栈顶,如果位于栈顶就不用再重新创建了只会调用一下 onNewIntent方法。如果不是位于栈顶,则会创建一个新的Activity实例。
3.SingleTask : 这个就比较类似于SingleInstance 有什么相似的地方:系统中只创建该Activity的一个实例。有什么不同的地方,SingleTask 不会另外创建一个新的Task,而 SingleInstance会。 这是针对于整个Task 去查看一个Activy的存在情况,如果这个Task里已经存在这个Activy,则会把这个Activity在堆栈上面的Activity全都释放掉,让这个Activity回到栈顶,然后调用OnNewIntent方法。额外强调,这些都是在没有涉及到Affinity的,如果涉及到Affinity 接下来另讲
一个名词:TaskAffinity
什么意思,它是<activity>的一个元素,用于关联task,默认情况下,泳衣应用中所有的Activity 优先位于相同的Task中。哪里都有一个但是:我们可以修改Activity默认关联的Task,即我们可以为同一应用的Activity匹配不同的Task
这个属性的值是什么,一个字符串,一个软件的报名。
什么情况下回有用呢
1.我们启动Activity 时的 Intent 包含 FLAG_ACTIVITY_NEW_TASK标志
这是啥意思呢,当包含这个标志时,系统会寻找其他Task来存Activy,通常这是一个新的Task,不过如果现在已经有一个Task 具有和Activity相同的关联(Task也是根据报名创建的),这个Activity就会移到该Task中,否则会重新创建一个新的TASK
2.Activity 将其属性 allowTaskReparenting 设置为true
这种情况下,Activity可以从启动的任务,移动到与这个Activity相关联的Task中(如果该任务出现在前台)。
例如,假设将报告所选城市天气状况的 Activity 定义为旅行应用的一部分。 它与同一应用中的其他 Activity 具有相同的关联(默认应用关 联),并允许利用此属性重定父级。当您的一个 Activity 启动天气预报 Activity 时,它最初所属的任务与您的 Activity 相同。 但是,当旅行应 用的任务出现在前台时,系统会将天气预报 Activity 重新分配给该任务并显示在其中
提示:如果从用户的角度来看,一个 .apk
文件包含多个“应用”,则您可能需要使用 taskAffinity
属性将不同关联分配给与每个“应用”相关的 Activity。
这里还有清理返回栈的一个属性
两个是针对于Task中所有的Activity的,一个是针对于单独的Activity的
alwasRetainTaskState 属性为true,当这个Task后台执行,即使过了很久也不会把这个Task中的Activity销毁
相反的一个 ClearTaskOnLaunch 设置为true 只要把Task置于后台,则会清理堆栈中的Activity只剩下根Activity。
finishOnTaskLaunch
针对于单独的Activity 只要Task置于后台,这个Activity就会被销毁(慎用,有可能会导致出错)