zoukankan      html  css  js  c++  java
  • Activity启动模式 及 Intent Flags 与 栈 的关联分析

       在学习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"

    下面举例说明它们的差别:


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


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


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


    singleInstancesingleInstance模式下,会将打开的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 ,此时点击返回button,还是在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 与 栈 的关联分析,便于之后一篇文章中跳转模式的了解使用。
  • 相关阅读:
    python2.7升python3.2
    SQL-基础学习使用的数据库资料
    SQL-基础学习2--ORDER BY ,DESC,WHERE, BETWEEN,AND ,OR ,IN ,NOT
    SQL-基础学习1--SELECT,LIMIT,DISTINCT,注释
    Python之Django-part 1
    python--文本处理1
    EXTJS4.2——8.Form+gride+linq进行前后端传输
    LINQ的实例
    高级委托使用
    C# 委托
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4303200.html
Copyright © 2011-2022 走看看