Android基础之Activity启动模式

Android的启动模式

Task与Back Stack
·Task表示“作业”或“任务”。
·在Android系统中,执行某个任务可能存在多个与用户产生交互的Activity,Task则是这些Activity的容器。
·执行Task的多个Activity不一定归属于同一个应用程序
·执行Task的多个Activity中,可能有同一个Activity的多个实例。
·Task使用Back Stack保存、管理各个Activity。
·Back Stack表示“回退栈(后退栈)”。
·每个Back Stack最顶端(栈顶)的Activity被置于前台,称之为Foreground Activity.即“前台Activity”。
·Back Stack有压栈(Push)和出栈(Pop)的操作,且遵循“先进后出,后进先出”的原则。

·Tack作为一个容器,使用Back Stack保存,管理各个Activity。
·用户在使用Android设备时,可以启动多个Task。
·每个Task都是一个有聚合力的单元,它可以在用户启动一个新的Task或按下HOME键返回桌面时整体的被置于后台。
·无论Task置于前台或后台,其Back Stack都是完整的保存的,因此,用户在执行某个Task时,另外启动了新的Task,则原Task被置于后台,但当原Task重新被置于前台时,它的Back Stack依然存在。

LaunchMode
·launchMode表示“启动模式”。
·当Activity的launchMode被配置为不同的值时,当尝试激活Activity时,可能会受影响:
-该Activity的实例数量不同;
-所在的Task会不同;(在Activity中通过getTaskId()可查看Task的ID)
-在Back Stack中列表不同;
-在Back Stack中各Activity经历的生命周期不同。

如何配置Activity的launchMode
·开发人员可以在项目的AndroidManifest.xml中配置”activity”节点的launchMode属性。

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:launchMode="***">
</activity>

Activity的4种launchMode

·standard
-标准模式,每次激活Activity时均在当前任务栈中创建新的实例。
注:任务栈相同,但是实例有多个
这里写图片描述
·singleTop
-位于任务栈时唯一,如果当前Activity已经位于当前任务栈的栈顶,则不会创建新的实例。
这里写图片描述
这里写图片描述
·singleTask
-独立于任务栈,如果该Activity的实例不存在,则创建并获得栈顶位置,如果实例已经存在,则其上方的Activity均出栈,且该Activity获得栈顶位置。
这里写图片描述
这里写图片描述
·singleInstance
-实例唯一,实例独占任务栈,且无论哪个任务栈共享同一个Activity的实例。
-该Activity有独立的Task,且在Task中唯一,由该Activity激活的其它Activity归属于其它Task。
这里写图片描述

singleInstance与taskAffinity
·由被配置为singleInstance的Activity激活的其它Activity,会尝试放在存在“亲属”关系的Task中,如果没有匹配的Task存在,则会创建新的Task存放被激活的Activity。

什么是taskAffinity
·Affinity表示Activity的“亲属关系”。
·在AndroidManifest.xml文件中,可以为每个Activity配置taskAffinity属性,表示该Activity希望进入的Task,该属性的值是字符串。

taskAffinity属性
·默认情况下,同一个应用程序中各个Activity的taskAffinity属性值均相同,则表示使用Application的taskAffinity,如果Application没有指定该属性,则默认为项目的包名。
·在配置taskAffinity属性时,取值应参考包名的命名格式,且不应该使用下划线(_),避免应用程序在编译打包时出现问题。

singleTask与taskAffinity
·情景:
-SingleTaskActivity的launchMode配置为singleTask;
-使用另一个应用程序的Activity去激活SingleTaskActivity;
-SingleTaskActivity与激活它的Activity配置了不同的taskAffinity。
·结论:
-SingleTaskActivity与激活它的Activity在不同的Task中。

allowTaskReparenting
·Activity能否从启动的Task移动到存在“亲属”关系的Task(当这个Task进入到前台时)。
·该属性取值为true或false。
·情景:
-ActivityA的allowTaskReparenting设置为true;
-Activity所在的应用程序APP1当前显示另一个ActivityB;
-使用另一个应用程序APP2激活该APP1中的ActivityA;
·结论:
-直接回到桌面(2个APP均不退出时),重新点击APP1的图标,会直接启动APP1的ActivityA,而该Activity是由APP2启动的,且按BACK键会回到APP1的ActivityB,后续再点击APP2的图标时,可以发现其任务中已经没有ActivityA。

alwaysRetainTaskState
·Activity所在的Task的状态是否总是由系统来保持,即该Task可能长期被置于后台,但系统不会对其进行清理。
·该属性取值为true或false,默认值是false。

clearTaskOnLaunch
·当Task被置于后台,是否清楚Task中除了根Activity以外的它他所有Activity。
·该属性取值为true或false。

finishOnTaskLauch
·当Activity已经启动,且其所在的Task被置于后台之后,如果Task再次回到前台,是否清楚已经存在的实例。
·该属性作用于单个Activity。
·该属性取值为true或false,默认为false。

noHistory
·当Activity被置于后台之后,是否将其从Back Stack中清楚并结束。
·该属性取值为true或false,默认为false。

Intent中关于激活Activity的Flag
·Intent类定义了一批常量,用于配置激活Activity时的相关参数:

在Intent中设置Flag
·调用Intent的setFlags()或addFlags()可以配置Intent的Flag属性。

FLAG_ACTIVITY_NEW_TASK
·尝试开启新的Task,可能产生的效果:
-如果当前已有Task与尝试激活的Activity的taskAffinity相同,则在该Task中直接压栈,被激活的Activity获得栈顶位置;
-如果当前没有Task与尝试激活的Activity的taskAffinity相同,则创建新的Task,且被激活的Activity获得栈顶位置。

·例如:
-APP1中存在ActivityA与ActivityB,当前ActivityA已经激活,通过APP2激活APP1的ActivityB,回到桌面并点击APP1的图标,会直接显示ActivityB,在整个过程中,APP1的2个Activity的Task ID相同,APP2的Activity是另一个Task ID.

FALG_ACTIVITY_CLEAR_TASK
·清空被激活的Activity应该归属的Task,且被激活的Activity添加到该Task中获得栈顶位置。
·该Flag应与FLAG_ACTIVITY_NEW_TASK一同使用。

FLAG_ACTIVITY_SINGLE_TOP
·位于栈顶时唯一,其特性可参考将”activity”中launchMode属性配置为singleTop。

FLAG_ACTIVITY_CLEAR_TOP
·清楚顶部,可能产生的效果:
-情景1:当Intent尝试激活的Activity的实例在Task中不存在时,创建该Activity的实例,并获得栈顶位置;
-情景2:如果该Activity的实例已经存在,则清除Task中该实例之上的所有Activity,且获得栈顶位置;
-情景3:在情景2的基础上,如果该Activity的launchMode属性不是single或singleInstance,该Activity原本存在的实例也会被移除,位于栈顶的是最新创建的该Activity的实例。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
·当Task被Reset时,清除该Activity及在Task中位于该Activity之上的所有Activity。
·当Task被置于后台,且重新被置于前台是,则可能被Reset(由系统添加FLAG_ACTIVITY_RESET_TASK_IF_NEEDED),通常通过点击应用程序图标回到前台时会Reset,而通过任务列表则不会。

FLAG_ACTIVITY_NO_HISTORY
·当Activity被置于后台之后,是否将其从Back Stack中清除并结束,其特性可参考”activity”的noHistory属性。

激活Activity与压栈
·当Activity被激活时,它在Back Stack中压栈,成为栈顶Activity,则被显示且获得焦点。
·以第1次启动某个应用程序为例:
-大多数的Task以HOME界面,或应用程序列表界面作为起点,当用户点击应用程序图标时,Task被创建且置于前台,系统检索到入口Activity后在Back Stack中压栈,由于Task是新创建的,则此时Back Stack中只有一个Activity,入口Activity即是栈低Activity也是栈顶Activity,所以入口Activity被显示且获得焦点。

保存Activity的状态
·当同一个Task中,出现新的Activity压栈时,或当前Task被整体的置于后台时,原Task栈顶的Activity被停止时的状态将被保存。
-例如:在某个应用程序的登录界面中,输入了用户信息,然后被来电中断,当通话结束后,原登录界面中已经输入的信息依然存在。
-注意:由于系统可能以为资源不足而销毁一些Activity,所以并不能保证当Task被置于后台之后,再次回到前台时Activity的状态依然存在,因为很可能整个Activity都已经不存在了。

Activity的销毁与出栈
·当用户点击“Back”键时,栈顶的Activity出栈,一旦出栈,则该Activity被终止,且资源被回收,即销毁。

Activity的状态与Back Stack
·在Back Stack中,Activity的状态可能为:
-当新激活的Activity压栈,则成为栈顶Activity,该Activity处于运行态;
-当用户点击“Back”键,栈顶Activity出栈,且被销毁,处于终止态;
-在栈内,且不处于栈顶的Activity,可能处于暂停态,停止态,终止态。

Activity的生命周期方法
·当激活Activity时:
·配置为standard模式时,经历:
-onCreate()->onStart()-onResume()
·如果Activity已经置于后台,且不需要创建实例(例如singleTop模式、singleTask模式、singleInstance模式),则经历:
-onPause-onResume()
·如果Activity已经置于后台,且不需要创建实例(例如singleTask模式、singleInstance模式),则经历:
-onRestart()->onStart()->onResume()
·强制出栈的Activity都会经历onDestroy().

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值