Android原理探究:Activity任务栈Task的简单探讨
来源:互联网 发布:地下城组队网络冲突 编辑:程序博客网 时间:2024/05/16 15:07
转载请注明出处,谢谢~
http://blog.csdn.net/net_168/article/details/50958700
案例
某天上班,小明正在调试前些日子开发的支付宝应用内支付功能。当他兴冲冲打开支付页面,不小心把APP切到后台,等返回APP时却发现支付界面莫名其妙消失了,又发现那个支付界面又偷偷跑到了隔壁支付宝APP那边。小明突然感觉背脊一凉,产品经理那阴冷冷的话仿佛音绕耳旁:搞定这个BUG,你只有两个小时。可是左猜又蒙想不起个所以然,这不对呀,小明的世界观开始出现裂隙;不行,得去请教老司机,错了,是求助老员工。而老司机听了小明的疑惑后色眯眯的说,这是正常的现象呀!纳尼~小明的世界观彻底的崩溃了,还能这么玩。
Android的taskAffinity与Task
在老司机的引路下,小明翻阅了几篇82年的文档压压惊。发现,貌似跟activity里面的属性taskAffinity这个东西有点关系。这里需要科普下:taskAffinity中文翻阅“亲和力”,说人话就是“Activity抱团打BOSS”;然而文档又说明拥有相同taskAffinity的Activity一般情况下会组成一个Task集合。
而这个Task干嘛的?举个栗子:当我们从桌面启动了应用A,应用A里面包含了Activity1、Activity2,估计记做A1、A2;如果这时又有一个应用B,拥有B1、B2、B3这些Activity。那么我们可以姑且认为他们不是一伙的:A1、A2属于一个Task,而B1、B2、B3属于另外一个Task。然而谷歌设计这个Task到底有什么不可告人的秘密呢?
带着然并卵的疑问,小明又发现了谷歌对于Task用途的一个权威解释:Task的引入是为了确保Activity的启动和退出的顺序,顺便来个情景分析,如果系统中Activity的顺序是A1-A2-A3-B1-B2-C1-C2,那么我们要在C应用中C2这个Activity启动属于B应用的B1这个Activity,那么问题来了:
1、程序要启动B1,但从用户角度来看,可能是要启动B2,因为B1和B2是两个相关联的Activity,且B2在B1之后。那么虽然是启动B1,既然B2已经在运行了,那就启动B2吧。
2、如果已经从C2跳转到B2,那么在B2进行”BACK”键回退时,是应该回到C2呢还是B1呢?
为了解决这两个问题,谷歌引入了Task:当启动Activity时,系统会根据Activity的taskAffinity属性去找对应的Task(前提是采用了Intent的Flag:NEW_TASK配置)。如果存在相对应的TASK(B1-B2);这不是找到组织了嘛,那就强行抱团插队到TASK的最前面,也就是A1-A2-A3-C1-C2-B1-B2,那么B2回退时,顺理成章得回到B1,也就解决了上面那两个问题。
Activity的launchMode和Flag
那么什么会影响Activity的不同Task归属呢?智商捉鸡的小明隐隐约约想起了一直熟背的Activity四大启动模式和一直觉得很神秘的Flag,很明显他们都是对于分配Activity从属哪个Task的决定性因素。小明翻阅他的开发红宝书,记有如下内容:launchMode有standard、singleTop、singleTask和singleInstance等四种模式;Flag有FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_NO_HISTORY等等等(PS:那么多,记得下也记不住)。可是他们两种有什么区别么?鬼知道呀。能用就用呗~
可是,launchMode和flag是怎么决定Task的归属和顺序的?带着这些疑惑,小明是茶也不思、饭也不香。于是,又从各个小道打探消息,终于找茫茫百度之间找到这么一句话:Android关于Task的设计理念有一个简单的原则,如果是跨Task切换,调用者是没有权利去更改被调Task里面的Activity的顺序,除非被调用者自己声明了某些属性。
稍微翻译一下,也就是说如果Activity顺序是A1-A2-B1-B2-B3-C1-C2-C3那么在C3中启动B的三个Activity里面任意一个,其结果只能是 A1-A2-C1-C2-C3-B1-B2-B3,只能是整个B栈的切换调整;而如果C3启动C中任意的Activity的话,是可以对C中的Activity的顺序进行重排的,因为C正在与用户交互,系统认为当前交互的任务(Task)中切换Activity是合法的。在这个设计原则前提下,我们就很容易对各种启动方法导致的启动结果做出一个分析:
进行Task切换的方法有两种,一种是在AndroidManifest.xml里面声明Activity自身的启动属性,另外一种则是启动时为Intent添加对应的Flag。东西比较多,小明比较懒就没一一罗列出来。各种模式各种标识,看起来炒鸡复杂~
但是,小明又发现有前辈总结了这么一个大定律。记录如下:虽然Activity的启动方式繁杂,但总得来说分为三种主要类型:第一类是为了完成在Task之间的切换;第二类是为了完成在当前Task改变其中的Activity的顺序;最后一类则是Task在切换时内部自动重排Activity的顺序。
稍微举个例子来加深印象:
第一类:在Task之间的切换,我们可以通过在intent里面设置FLAG_ACTIVITY_NEW_TASK来启动Activity,很显然,如果intent所匹配到的Activity已经存在于某个Task里面,那么就直接切换到这个Task;如果没有则会创建一个新的Task来容纳该Activity。或者是调用者自身就希望出现在一个新的Task里面,例如launchMode的singleInstance属性。
第二类:在同一个Task里面调整Activity的顺序,但需要注意的是只能调整当前Task里面的Activity的顺序,例如我们可以使用CLEAR_TOP这个flag来清楚目标Activity上面的其他Activity,或者使用NO_HISTORY使得目标Activity常驻在Task之中,或者使用launchMode的singleTask来显示类似的效果。
第三类:让被调Task再启动前主动重排,这个并不多用,简单说是例如发起intent的标识为RESET_IF_NEEDED或者在清单文件里面使用android:clearTaskOnLauch等属性,字面意思很清楚了,这里就不往深讲了。
回顾
经过小明风风雨雨的研究心路历程,小明对开头的问题作了如下分析:
1、在APP中启动了支付页面,但是支付页面是从属于另外的一个APP(也就是支付宝);所以该支付页面一般来说也就是属于另外一个Task,暂且把自己的APP所属的Task记为A、支付宝所属的Task记为B。
1、有人告诉小明桌面其实也是一个APP,桌面页面所在的Activity当然也是从属于某一个Task里面,记桌面所在的Task为C。
2、此时我们可以知道Activity的顺序为B1-A1-A2-A3-C1,那么我们从APP切回桌面时,顺序应该变成A1-A2-A3-C1-B1。那么我们如果继续点击我们APP的图标,很明显顺序应该是C1-B1-A1-A2-A3,也就是C1这个支付页面就消失了;如果不点击APP图标而点击支付宝图标,顺序则是A1-A2-A3-B1-C1,很明显现在调起来的是支付界面。
完结~小明突然觉得自己挺叼炸天的O(∩_∩)O哈哈~
- Android原理探究:Activity任务栈Task的简单探讨
- Activity的任务栈:Activity Task
- android task任务栈(Activity)
- android的task任务栈
- android的task任务栈
- android的task任务栈
- android的task任务栈
- android的task任务栈
- Android Task任务栈
- Android task任务栈
- Activity的启动模式,任务栈Task,intent的Flags
- Android中Task任务栈的分配
- Android中Task任务栈的分配
- Android的任务栈task stack
- Android中Task任务栈的分配
- android task栈和activity的关系(Task/launchMode)
- android task栈和activity的关系
- Activity启动模式与任务栈(Task)
- GNU开发笔记--开发环境基础(持续更新)
- Jsp
- java:double四舍五入并保留两位小数的方法
- 商业即生活,一些思考和感悟
- Problem-1016
- Android原理探究:Activity任务栈Task的简单探讨
- 二叉树的生成和遍历
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Python学习笔记(一)
- Ubuntu14.04下“E: 无法找到软件包”的解决
- ubuntu14.04LTS丢失登录界面
- 一人一狗,那一年
- JSONObject 解析json的步骤
- 机器学习中的特征工程总结一