在学习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.什么是栈


<span style="font-size:14px;">栈是一种常用的数据结构,栈只允许访问栈顶的元素,栈就像一个杯子,每次都只能取杯子顶上的东西,而对于栈就只能每次访问它的栈顶元素,从而可以达到保护栈顶元素以下的其他元素.”先进后出”或”后进先出”就是栈的一大特点,先进栈的元素总是要等到后进栈的元素出栈以后才能出栈.递归就是利用到了系统栈,暂时保存临时结果,对临时结果进行保护.</span>
<span style="font-size:14px;">
</span>
<h2 style="font-weight:bold; font-family:arial,'courier new',courier,宋体,monospace"><a target=_blank name="t2"></a><span style="font-size:18px;">定义栈(Stack)</span></h2><span style="font-family:arial,'courier new',courier,宋体,monospace;font-size:14px;color:#333333;"><strong>栈的定义栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。(1)通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。 (2)当表中没有元素时称为空栈。(3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表。栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。</strong></span>
<span style="font-family:arial,courier new,courier,宋体,monospace;color:#333333;"><span style="font-size:14px;"><strong>
</strong></span></span><h2 style="font-weight:bold; font-family:arial,'courier new',courier,宋体,monospace"><a target=_blank name="t3"></a><span style="font-size:18px;">栈的操作</span><span style="font-size:14px;color:#333333;">:压栈、弹栈 </span></h2><div style="color:rgb(51,51,51); font-weight:bold; font-family:arial,'courier new',courier,宋体,monospace; font-size:14px">
</div><h1><a target=_blank name="t4"></a><span style="font-family:KaiTi_GB2312;font-size:24px;">2.Activity中的栈</span></h1><div><span style="font-family:KaiTi_GB2312;font-size:24px;">
</span></div>
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的启动模式和栈管理的更多相关文章

  1. Android开发艺术2之Activity的启动模式

    Activity是Android的四大组件之一,他的重要性毋庸置疑,对于这么重要的一个组件,我们首先要知道这些都是由系统进行管理和回调的,要理解Activity的启动模式,我们首先来了解一下Andro ...

  2. 06 Activity的启动模式 Intent的七大属性的总结

    1.Task以及back stack     >Task(任务)  为了完成一个功能  多个Activity的集合,     当你的应用程序启动时 系统会自动创建Task用于管理Activity ...

  3. Android笔记(五) Activity的启动模式

    Android中Activity是由返回栈来管理的,在默认情况下,每当启动一个新的Activity,它都会在返回栈中入栈,并且出于栈的顶端.但是有些时候Activity已经在栈的顶端了,也就不需要再启 ...

  4. 关于activity的启动模式

    在Android中每个界面都是一个Activity ,界面的切换实际上是对不同Activity实例化的过程.而启动模式就决定Activity启动运行方式. 1.设置方式它是在主配置文件中,Activi ...

  5. 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)

    1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...

  6. android Activity的启动模式与flag的见解

    最近做一个安卓项目,想要实现的效果就是:当打开一个按钮的时候,启动了一个A功能,当用户返回到桌面再继续进去的时候,不过之前在哪个Activity,都会先跳转到A功能的那个界面,当用户点击返回的时候,再 ...

  7. android Activity的启动模式

    Android中Activity启动模式详解   在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启 ...

  8. Activity的启动模式(android:launchMode)

    在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: ...

  9. 4种activity的启动模式

    在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: ...

随机推荐

  1. ●BZOJ 4408 [Fjoi 2016]神秘数

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 题解: 主席树 首先,对于一些数来说, 如果可以我们可以使得其中的某些数能够拼出 1- ...

  2. Polya计数

    Let it Bead Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5365   Accepted: 3585 Descr ...

  3. [bzoj1143][CTSC2008]祭祀

    题意:给定一个n个点m条边的有向无环图,你要选出最多的点,并且满足任意两点之间都不存在通路.2)输出每个点选了它之后还是否有最优解.   n<=100 m<=1000 题解:每个点拆两个点 ...

  4. SpringCloud学习之Hystrix

    一.为什么要有断路器 在分布式系统当中,服务之间调用关系会随着业务的发展而变的复杂,一个服务可能依赖多个服务,服务之间层层依赖也是家常便饭的事情,如果一个服务的瘫痪很有可能导致整个系统的崩溃.比如说, ...

  5. 安装yum源和gcc编译器遇到的问题

    这两天我试着在VMware虚拟机里安装gcc,遇到了不少问题 1.   安装yum源 我搭建的是光盘yum源(有两种方法搭建yum源,另外一种是网络yum源,但至今没弄懂我的网络yum源为什么不成功) ...

  6. 使用VMware Converter Standalone Client进行虚拟机 P2V提示 权限不足,无法连接\\ip\admin$的解决方法集锦

    使用VMware vCenter Converter Standalone Client进行虚拟机 P2V提示 权限不足,无法连接\\ip\admin$的解决方法集锦 步骤一 检查 远程桌面到&quo ...

  7. getBoundingClientRect方法获取元素在页面中的相对位置

    获取元素位置可以用 offset 或 getBoundingClientRect,使用 offset 因为兼容性不好,比较麻烦,offset获取位置会形成"回溯".而 getBou ...

  8. easyui datagrid 动态表头2

    前端 function goqry() { $("#form").form("submit", { url: "CJCK_bjcjfx_yfsl.as ...

  9. java底层学习

    额,马上就要面试了,Java的底层肯定是需要了解的.网上找了找java的底层文章,做个记号.java底层主要是类的加载.连接和初始化. 本文主要分为四个方面: (1)java底层概述 (2)new和n ...

  10. tomcat7+jdk的keytool生成证书 配置https

    目前只会使用jdk的keytool来生成证书.本文仅介绍这种方法. 1Windows下: 1.1 生成keystore文件及导出证书 打开控制台: 运行: %JAVA_HOME%\bin\keytoo ...