这里会以多个场景列子进行分析,在分析之前先了解一下基本的概念。

Task任务:一系列Activity的集合,这些Activity以栈的形式进行排列(后进先出)。

那在什么时候系统会新建一个Task任务呢?

这个要以app来区分(注意,这里看Activity是否属于同一报名),当一个app以singleTask启动方式启动另外一个app的activity时,会新建一个Task任务,而第二个app的Activity会成为这个栈中的根。

反之,在什么时候不会创建新任务呢?当一个app以非SingleTask方式启动另一个app时,或者在同一app内无论以什么方式启动其他Activity,都不会创建新的任务。

上面的说法会在之后的场景中一一进行验证。

长按HOME键后,在最近打开的任务中可以看见新创建的Task。

各个应用程序都是由launch启动的,首先来分析launch这个Activity。launch是由系统启动(由 ActivityManangerService启动),当launch启动后,相当于启动一个Task,简称Task1,launch这个 Activity成为Task1维护的栈中的根元素。这里,当在launch中点击app1启动图标不会在Task1中继续添加,而是会为app1新建一 个Task任务,原因如下

  1. boolean startActivitySafely(Intent intent, Object tag) {
  2. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  3. try {
  4. startActivity(intent);
  5. return true;
  6. } catch (ActivityNotFoundException e) {}
  7. }

launch启动其他Activity都是以new task的方式启动的。这样每启动一个app,都会新建一个任务(如果任务不存在)。这样多个任务就产生了,点击HOME键的时候会启动Launch,相 当于把Launch这个任务从后台移动到前台,这个时候继续点击app1,也就相当于把app1(前提app1的第一个activity在配置文件中的启 动模式声明不是aingleTask)所在的任务移动到前台显示,而不会重新排布app1中所有Activity的位置。

模拟一下两个Task的场景

场景1. 从Task1中的launch中打开app1,会新建Task2,Task2的根为Activity_a,启动模式为默认,从Activity_a中打开 Activity_b.,然后从Activity_b中点击HOME回到Launch,再点击app1,这个时候相当于直接把Task2从后台移动到前 台,Task1处于后台,Task2维护栈中的Activity位置不变,Activity_b依然处于栈顶,显示在最前端。

场景2. 从 Task1中的launch中打开app1,会新建Task2,Task2的根为Activity_a,启动模式为SingleTask,从 Activity_a中打开Activity_b.,然后从Activity_b中点击HOME回到Launch,再点击app1,这个动作会先判断 Task2的根Activity是否是SIngleTask,如果是,则执行Activity_a的onNewIntent()方法,destory掉Activity_b。如果不是直接把Task2移动到前台显示。

(注意:场景2如果不是从launch中点击图标进入,而是从显示的最近任务中进入,则不会判断根Activity的启动模式,会直接把Task2移动到前台。Task2中的Activity排列方式不变)

模拟一下3个Task的场景

条件:Task1中一个Launch, Task2中app1含Activity_a,Activity_b , Task3中app2含Activity_D,Activity_E,Activity_F。

场景1:从launch中进入Activity_a,然后进入到Activity_b,在Activity_b中以普通模式打开Activity_e(可以通过隐式启动打开),然后在Activity_E 中打开Activity_F,虽然从Task2中打开了另一个app的Activity,但是由于是默认模式打开的,所以不会创建新任务 Task3,Activity_E和Activity_F都属于Task2,,这时候点击Home键回到Launch,再点击app1,会把Task2移 动到前台,显示出处于Task2最顶端的Activity_F,最近显示的任务中也不会出现Task3.

场景2:从launch中进入Activity_a,然后进入到Activity_b,在Activity_b中以SingleTask模式打开Activity_e,然后在Activity_E中打开Activity_F,这个时候由于符合新建Task条件,不同app,singleTask启动,会新建Task3,然后在Activity_E中打开Activity_F,然后按home键进入到launch,发现最近任务中出现了task2,和task3,这时候点击app1发现Activity_b处于最顶端,点击app2发现该Task3已经存在,不会继续创建,显示Activity_F处于顶端,从Activity_F中点击返回键,依次回到Activity_E,最后launch,而不会回到Activity_D,因为Activity_D不在栈中。

 总结一下,

1:要创建新任务,至少要满足两个条件:不同app和以SingleTask方式启动,否则在同一个app中以SingleTask方式打开 Activity是不会新创建任务的。(这里有一个特殊情况,设置Activity的android:taskAffinity属性可以让 Activity看起来是属于另一个包,属于另一个Activity)

2.在最近任务中进行多个任务之间的相互切换时不会打乱每个任务中Activity的排列。但是在点击app图标进行多个任务切换时,系统会先判断该任 务根Activity的启动模式是否为SingleTask,不是的话,不做任何操作,如果是的话,执行根Activity的onNewIntent方 法,把覆盖在根Activity之上的Activity destory掉。

3.当没有创建新任务时,新打开的Activity会一直进行当前任务中进栈,无论这些个Activity是属于哪一个App。

Android多任务切换与Activity启动模式SingleTask之间关系的分析的更多相关文章

  1. Android Activity传递数据使用getIntent()接收不到,揭秘Intent传递数据与Activity启动模式singleTask的关系。

    activity通过intent传递数据的时候,如果activity未启动,那么在这个刚启动的activity里通过getIntent()会获取到这个intent的数据.. 如果要启动的activit ...

  2. Android组件体系之Activity启动模式解析

    本文主要分析Activity的启动模式及使用场景. 一.Activity启动模式浅析 1.standard 标准模式,系统默认的启动模式.在启动Activity时,系统总是创建一个新的Activity ...

  3. Android中Activity启动模式详解

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...

  4. Android Activity 启动模式详解

    最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...

  5. 【转】Android总结篇系列:Activity启动模式(lauchMode)

    [转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...

  6. AndroidのActivity启动模式

    Activity启动模式      .概念      Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否    .属性     Activity的启 ...

  7. activity启动模式之singleTask

    activity启动模式之singleTask 一.简介 如果另外一个应用调用了C2,C2在栈底,如果这个程序里面再嗲用C1,C3,C2,那么这个C2就是调用onNewIntant的,C1和C3都被销 ...

  8. Activity启动模式 及 Intent Flags 与 栈 的关联分析

     http://blog.csdn.net/vipzjyno1/article/details/25463457    Android启动模式Flags栈Task   目录(?)[+] 什么是栈 栈 ...

  9. 【转】Activity启动模式 及 Intent Flags 与 栈 的关联分析

    http://blog.csdn.net/vipzjyno1/article/details/25463457    在学习Android的过程中,Intent是我们最常用Android用于进程内或进 ...

随机推荐

  1. 【Java Concurrency】sleep()、wait()、notify()、notifyAll()的用法与区别

    >关于本文 本文介绍sleep().wait().notify().notifyAll()方法,主要要理解: sleep()和wait()的区别. wait()与notify().notifyA ...

  2. DIOCP开源项目-DIOCP3的重生和稳定版本发布

    DIOCP3的重生 从开始写DIOCP到现在已经有一年多的时间了,最近两个月以来一直有个想法做个 30 * 24 稳定的企业服务端架构,让程序员专注于逻辑实现就好.虽然DIOCP到现在通讯层已经很稳定 ...

  3. vue中创建全局单文件组件/命令

    1.在 vue中如果我们使用基于vue.js编写的插件,我们可以使用Vue.use() 如在main.js中: 2.添加全局命令,让每个vue单文件组件都可以使用到: 第一步:最好建一个全局的命令文件 ...

  4. 【转】解决Lost connection to MySQL server during query错误方法

    初步判断是MySQL可能挂掉了,在系统服务里面查看MySQL的进程并没有停止. 最开始考虑是数据库结构不对,但是我是通过Navicat for MySQL的备份和恢复备份导入数据,应该表结构都在备份文 ...

  5. 使用卷积神经网络CNN训练识别mnist

    算的的上是自己搭建的第一个卷积神经网络.网络结构比较简单. 输入为单通道的mnist数据集.它是一张28*28,包含784个特征值的图片 我们第一层输入,使用5*5的卷积核进行卷积,输出32张特征图, ...

  6. linux下保护视力、定时强制锁定软件: Workrave

    超负荷地工作会累坏身体的,而且效率也不高,所以工作一段时间就应该休息一下.长时间在电脑前一动不动,很容易患上“重复性劳损”,即 Repetitive Strain Injury (RSI).具体现象大 ...

  7. mysql处理varchar类型的between和and的时间问题少一天解决;

    select * from table where CJSJ day),"%Y-%m-%d") 数据库中的时间类型是varchar,传入的类型也是string 上述sql的意思是: ...

  8. 【.Net】Thread.Start()与ThreadPool.QueueUserWorkItem()的区别

    百度搜到的靠前的几篇文章,都是写了两种API的使用实例,但并没有说清两者的具体差别. 直接上stackoverflow搜才是正确的姿势.(想上谷歌,然而十/九_大|期间VPN各种被墙,就很气) 参考: ...

  9. 【Java/Spring】Spring的配置问题,IDEA报错“No mapping found for HTTP request with URI […] in DispatcherServlet”

    从SVN上拷贝下JavaWeb项目,Spring框架的配置文件需要修改.部署好Tomcat后,启动服务,可以进入Web项目主页,但是访问其他URL时直接跳转到404,IDEA报错“No mapping ...

  10. iptables nat 外网nat到内网在只限制外网访问的单一ip地址

    166 /etc/init.d/iptables start 167 iptables -I INPUT -s 192.168.10.0/24 -p tcp -j ACCEPT 168 /etc/in ...