http://blog.csdn.net/vipzjyno1/article/details/25463457

   在学习Android的过程中,Intent是我们最常用Android用于进程内或进程间通信的机制,其底层的通信是以Binder机制实现的,在物理层则是通过共享内存的方式实现的。
    Intent主要用于2种情景下:(1)发起意图  (2)广播
    它的属性有:ComponentName,action,data,category,extras,flags等,通常情况下,进行Intent的匹配涉及到3个属性:Action,Data,Category。这些东西都需要了解才能对它有个深入的体会。
    下面我就根据近期学习,总结记录下Activity启动模式 及 Intent Flags 与 栈 的关联分析。
 
 
文章结构:
 
1.什么是栈
2.Activity栈
3.Task
4.Activity启动模式
5.Activity栈和Task联系
6.Intent Flags 
7.Activity相关属性taskAffinity
 

1.什么是栈

 

栈是一种常用的数据结构,栈只允许访问栈顶的元素,栈就像一个杯子,每次都只能取杯子顶上的东西,而对于栈就只能每次访问它的栈顶元素,从而可以达到保护栈顶元素以下的其他元素.”先进后出”或”后进先出”就是栈的一大特点,先进栈的元素总是要等到后进栈的元素出栈以后才能出栈.递归就是利用到了系统栈,暂时保存临时结果,对临时结果进行保护.

定义栈(Stack)

栈的定义栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。(1)通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。 (2)当表中没有元素时称为空栈。(3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表。栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。

栈的操作:压栈、弹栈

 

2.Activity中的栈

Android的管理主要是通过Activity栈来进行,当一个Activity启动时,系统会根据其配置将它压入到一个特定的栈中,系统处于运行状态。当用户点击返回或则FINISH()了该Activity,那么它便会被从栈中压出,随之摧毁,按照Activity的生命周期可以知道,如果当前显示的栈中Activity没有被摧毁,那么打开新的Activity时候,会将新打开的压入到栈,原来的根据其显示情况选择状态变化(原Activity依旧可见,变为暂停状态(Paused),如果被完成遮住了,转变为停止状态(Stopped))。




3.Task


Task是与Activity相关的一个重要概念,它密切联系着Activity栈,它简单的说,就是一组以栈的模式聚集在一起的Activity组件集合。(这里只提它和Activity的启动模式来讲)
 

4.Activity启动模式

属性:android:launchMode  
作用:用于指示Activity如何启动。
描述:这里有四种模式,与Intent对象中的Activity Flags的属性(FLAG_ACTIVITY_*变量)共同作用,来决定Activity如何启动来处理Intent。
四种模式
    "standard"  --默认模式
    "singleTop"
    "singleTask"
    "singleInstance"
 

以下举例说明它们的区别:

standard:Activity的默认加载方法,该方法会通过跳转到一个新的activity,同时将该实例压入到栈中(不管该activity是否已经存在在Task栈中,都是采用new操作)。例如: 栈中顺序是A B C D ,此时D通过Intent跳转到A,那么栈中结构就变成 A B C D A ,点击返回按钮的 显示顺序是 D C B A,依次摧毁。

 

singleTop:singleTop模式下,当前Activity D位于栈顶的时候,如果通过Intent跳转到它本身的Activity (即D),那么不会重新创建一个新的D实例,所以栈中的结构依旧为A B C D,如果跳转到B,那么由于B不处于栈顶,所以会新建一个B实例并压入到栈中,结构就变成了A B C D B。

 

singleTask:singleTask模式下,Task栈中只能有一个对应Activity的实例。例如:现在栈的结构为:A B C D。此时D通过Intent跳转到B,则栈的结构变成了:A B。其中的C和D被栈弹出销毁了,也就是说位于B之上的实例都被销毁了。

 

singleInstance:singleInstance模式下,会将打开的Activity压入一个新建的任务栈中。例如:Task栈1中结构为:A B C ,C通过Intent跳转到了D(D的模式为singleInstance),那么则会新建一个Task 栈2,栈1中结构依旧为A B C,栈2中结构为D,此时屏幕中显示D,之后D通过Intent跳转到D,栈2中不会压入新的D,所以2个栈中的情况没发生改变。如果D跳转到了C,那么就会根据C对应的launchMode的在栈1中进行对应的操作,C如果为standard,那么D跳转到C,栈1的结构为A B C C ,此时点击返回按钮,还是在C,栈1的结构变为A B C,而不会回到D。

 

5.Activity栈和Task联系

 
Task简单的就是一组以栈的模式聚集在一起的Activity组件集合,类似于一个填充了Activity的容器,最先加入的Activity会处于容器最下面,最后加入的处于容器最上面,而从Task中取出Activity是从最顶端先取出,最后取出的是最开始添加Activity,这就是后进先出(Last
In First Out)模式,而Activity在Task中的顺序是可以控制的,在Activity跳转时用到Intent Flag可以设置新建activity的创建方式(这里就涉及到了Intent
Flag的使用)。
 

6.Intent Flags 

 
Flags: 表示Intent的标志位,常用于Activity的场景中,它和Activity的启动模式有着密切的联系。
下面列举的是和本文主题相关的Flags属性:
 
Intent.FLAG_ACTIVITY_NEW_TASK (默认)
 
默认的跳转类型,它会重新创建一个新的Activity,不过与这种情况,比如说Task1中有A,B,C三个Activity,此时在C中启动D的话,如果在AndroidManifest.xml文件中给D添加了Affinity的值和Task中的不一样的话,则会在新标记的Affinity所存在的Task中压入这个Activity。如果是默认的或者指定的Affinity和Task一样的话,就和标准模式一样了启动一个新的Activity.
 
FLAG_ACTIVITY_SINGLE_TOP
 
这个FLAG就相当于启动模式中的singletop,例如:原来栈中结构是A B C D,在D中启动D,栈中的情况还是A,B,C,D。
 
FLAG_ACTIVITY_CLEAR_TOP
 
这个FLAG就相当于启动模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。例如:原来栈中的结构是A B C D ,从D中跳转到B,栈中的结构就变为了A B了。(这个方法可以用来关闭多个Activity,之后的一篇博文里面会提到)
 
FLAG_ACTIVITY_BROUGHT_TO_FRONT
 
这个网上很多人是这样写的。如果activity在task存在,拿到最顶端,不会启动新的Activity。这个有可能会误导大家! 他这个FLAG其实是这个意思!比如说我现在有A,在A中启动B,此时在A中Intent中加上这个标记。此时B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式启动,此时在B中再启动C,D(正常启动C,D),如果这个时候在D中再启动B,这个时候最后的栈的情况是 A,C,D,B。如果在A,B,C,D正常启动的话,不管B有没有用FLAG_ACTIVITY_BROUGHT_TO_FRONT启动,此时在D中启动B的话,还是会变成A,C,D,B的。
 
FLAG_ACTIVITY_NO_USER_ACTION
 
onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而要退到background时使用。比如,在用户按下Home键,它将被调用。比如有电话进来(不属于用户的选择),它就不会被调用。
那么系统如何区分让当前activity退到background时使用是用户的选择?
 
它是根据促使当前activity退到background的那个新启动的Activity的Intent里是否有FLAG_ACTIVITY_NO_USER_ACTION来确定的。
 
注意:调用finish()使该activity销毁时不会调用该函数
 
FLAG_ACTIVITY_NO_HISTORY
 
意思就是说用这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比方说!原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。
 

7.Activity相关属性taskAffinity

 
Activity 中的 android:taskAffinity 这个属性介绍:

   Activity为Task拥有的一个affinity。拥有相同的affinity的Activity理论上属于相同的Task(在用户的角度是相同的“应用程序”)。Task的affinity是由它的根Activity决定的。 
   affinity决定两件事情——Activity重新宿主的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。
    默认情况,一个应用程序中的所有Activity都拥有相同的affinity。捏可以设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。为了明确Activity不宿主特定的Task,设定该特性为空的字符串。
    如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。
 
注:以上的android:taskAffinity只有通过标志位为FLAG_ACTIVITY_NEW_TASK的Intent启动Activity时,该Activity的这个属性才会生效,系统才会将具有相同Task亲和力的Task切换到前台,然后启动该Activity,否则该Activity仍然运行在启动它的Task中。
 
 
    上面总结了下Activity启动模式 及 Intent Flags 与 栈 的关联分析,便于之后一篇文章中跳转模式的了解使用。

【转】Activity启动模式 及 Intent Flags 与 栈 的关联分析的更多相关文章

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

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

  2. 关于Activity启动模式(launchMode)和intent设置测试后 发现和网上说的不符 是不是我错了 求解

    看了很多关于Activity启动模式(launchMode)和intent设置intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);发现网上说的和我测试结果 ...

  3. Activity的任务栈Task以及启动模式与Intent的Flag详解

    什么是任务栈(Task) 官方文档是这么解释的 任务是指在执行特定作业时与用户交互的一系列 Activity. 这些 Activity 按照各自的打开顺序排列在堆栈(即“返回栈”)中. 其实就是以栈的 ...

  4. Activity启动模式图文详解

    转载自:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0520/2897.html  英文原文:Understand Android A ...

  5. 详解Android Activity启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

  6. Android中Activity启动模式详解

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

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

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

  8. Activity启动模式(lauchMode)

    Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址 ...

  9. android:process结合activity启动模式的一次实践

    会有这样的场景,一个应用崩溃了,而导致的该应用崩溃的原因是,该应用占用的内存大小超过了系统分配给它的最大堆大小.对象的分配,是发生在堆(heap)上面的,系统分配给每个应用的最大堆大小是固定的. 假设 ...

随机推荐

  1. POJ 3352 Road Construction(边双连通分量,桥,tarjan)

    题解转自http://blog.csdn.net/lyy289065406/article/details/6762370   文中部分思路或定义模糊,重写的红色部分为修改过的. 大致题意: 某个企业 ...

  2. 【大数加法】POJ-1503、NYOJ-103

    1503:Integer Inquiry 总时间限制:  1000ms 内存限制:  65536kB 描述 One of the first users of BIT's new supercompu ...

  3. hihoCoder 1385 A Simple Job

    #1385 : A Simple Job 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Institute of Computational Linguistics (I ...

  4. c#写入Mysql中文显示乱码 解决方法 z

    mysql字符集utf8,c#写入中文后,全部显示成?,一个汉字对应一个? 解决方法:在数据库连接字符串中增加字符集的说明,Charset=utf8,如 MySQLConnection con = n ...

  5. HDU 4405-Aeroplane chess(概率dp)

    题意: n+1格飞行棋,编号0-n,从0格开始,每次扔一个色子,得到的点数就向前走几步,但有有些格子到达后可以直接飞到后面的格子, 当到达>=n的地方结束,求结束扔色子的期望次数. 分析: dp ...

  6. 《Python核心编程》 第六章 序列 - 课后习题

    课后习题 6–1.字符串.string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分? 答:成员关系操作符(in.not in) import string ...

  7. Ubuntu 12.04 pppoe拨号问题

    我的系统信息: Ubuntu 12.04.4 X64 Q001: 我学校需要使用pppoe拨号上网.我在宿舍架了个路由,可以使用无线连接拨号上网,也可以使用网线连接.在ubuntu下,使用无线连接时没 ...

  8. 如何在安裝SELinux的环境执行Quartus II

    (原創) 如何在安裝SELinux的環境執行Quartus II? (SOC) (Quartus II) (Linux) (RedHat) Abstract一般人安裝Linux時,也會同時安裝SELi ...

  9. poj1001 Exponentiation

    Description Problems involving the computation of exact values of very large magnitude and precision ...

  10. linux网络编程笔记——TCP

    1.TCP和UDP TCP是长连接像持续的打电话,UDP是短消息更像是发短信.TCP需要消耗相对较多的资源,但是传输质量有保障,UDP本身是不会考虑传输质量的问题. 2.网络传输内容 我习惯的做法是直 ...