android启动模式简介

来源:互联网 发布:企业网站排名怎么优化 编辑:程序博客网 时间:2024/05/16 04:28

学习内容:

1、栈的概念和原则;

2、activity的四种启动模式及对应的flags;

3、activity属性taskAffinity的简介和应用场景;

4、activity属性allowTaskReparenting、clearTaskOnLaunch、alwaysRetainTaskState和finishOnTaskLaunch的简介和应用场景


一、启动模式介绍

启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置;


启动模式有4种,分别为standard、singleTop、singleTask、singleInstance;

讲解启动模式之前,有必要先讲解一下“任务栈”的概念;


任务栈



进出原则是:每个Activity的状态是由它在Activity栈(是一个后进先出LIFO,包含所有正在运行Activity的队列)中的位置决定的。


当一个新的Activity启动时,当前的活动的Activity将会移到Activity栈的顶部。

如果用户使用后退按钮返回的话,或者前台的Activity结束,活动的Activity就会被移出栈消亡,而在栈上的上一个活动的Activity将会移上来并变为活动状态。


每个应用都有一个任务栈,是用来存放Activity的,功能类似于函数调用的栈,先后顺序代表了Activity的出现顺序;比如Activity1—>Activity2—>Activity3,则任务栈存放activity实例的顺序是1,2,3。


启动模式:


(1)standard:标准模式。每次激活Activity时(startActivity),都创建Activity实例,并放入任务栈;


相当于在intent中设置flags:

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);(默认)


(2)singleTop:如果某个Activity自己激活自己,即任务栈栈顶就是该Activity,则不需要创建,其余情况都要创建Activity实例;即是:要启动的目标Activity实例正好处于栈顶,才能重用该实例,其他情况必须创建新实例。


相当于在intent中设置flags:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);


(3)singleTask:栈单例模式。如果要激活的那个Activity在任务栈中存在该实例,则不需要创建,只需要把此Activity放入栈顶,并把该Activity以上的Activity实例都弹出栈;


相当于在intent中设置flags:

intent.addFlags(Intent. FLAG_ACTIVITY_BROUGHT_TO_FRONT);


(4)singleInstance:系统单例模式。如果应用1的任务栈中创建了MainActivity实例,如果应用2也要激活MainActivity,则不需要创建,两应用共享该Activity实例;


相当于在intent中设置flags:

intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);


 这里又一个疑问,还待找时间解决:FLAG_ACTIVITY_CLEAR_TOP和singleTask不一样的,singleTask不会销毁activity的实例,FLAG_ACTIVITY_CLEAR_TOP会把他上面的弹出,但是自身也销毁,然后重新创建个新对象。singleTop和FLAG_ACTIVITY_CLEAR_TOP结合才能达到singleTask的效果。



(5)这里还有其他的关于activity和intent flags的关系:

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。


(6)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中。


(7)activity其他属性:

  allowTaskReparenting

  clearTaskOnLaunch

  alwaysRetainTaskState

  finishOnTaskLaunch


关于allowTaskReparenting属性
    若一个activity组件的allowTaskReparenting被置为“true”,则当与这个activity有相同的亲属关系的任务栈被切换到前台的时候,这个activity会从当前存在的任务栈中移动到与其有相同的亲属关系的任务栈中。

   该配置还可以允许是否该activity可以更换从属task,通常情况二者连在一起使用,用于实现把一个应用程序的Activity移到另一个应用程序的Task中。


    若从用户的角度来看,一个.apk文件包含了一个以上的“应用程序”,那你可能要为那些activity组件指定不同的亲属关系。


引用网上的解释例子:

         一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。


alwaysRetainTaskState属性

    如果将根activity的alwaysRetainTaskState属性设置为“true”,则即便一个任务栈在很长的一段时间都被用户保持在后台的,系统也不会对这个任务栈进行清理。


alwaysRetainTaskState属性

    如果将根activity的alwaysRetainTaskState属性设置为“true”,则即便一个任务栈在很长的一段时间都被用户保持在后台的,系统也不会对这个任务栈进行清理。


finishOnTaskLaunch属性

    这个属性的行为类似于clearTaskOnLaunch,但是此属性作用于单个的activity对象,而不是整个任务栈。当这个任务栈切换到了后台,这个属性可以使任务栈清理包括根activity在内的任何activity对象。


0 0