您的位置:首页 > 移动开发 > Android开发

android启动模式简介

2016-05-21 12:46 447 查看
学习内容:
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对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: