1. Intent中影响Activity启动模式的FLAG
intent.setFlags(Intent.FLAG_ACTIVITY_????);
startActivity(intent);
1. FLAG_ACTIVITY_SINGLE_TOP
Same as"singleTop"。
2. FLAG_ACTIVITY_NO_HISTORY
也可以通过noHistory属性在manifest文件中指定:
<activity android:name=".ActivityB"
android:label="ActivityB"
android:noHistory="true">
</activity>
用于标记Activity是否会留下历史痕迹,即是否会在Activity stack中保留。
3. FLAG_ACTIVITY_NEW_TASK
与“singleTask”的不同在于红色字体:
当使用“FLAG_ACTIVITY_NEW_TASK”启动Activity时,系统首先会检查是否存在与该Activity的taskAffinity相同的task:
1. 如果task存在,直接实例化并入栈。所以,与“singleTask”不同的是,当Activity已经存在时,“FLAG_ACTIVITY_NEW_TASK”不会导致堆栈之上Activity的销毁和onNewIntent()的调用,,而是必定创建一个新的Activity实例。
2. 如果task不存在,那么就重新创建Task,并实例化入栈。
4. FLAG_ACTIVITY_CLEAR_TOP
如果设置,并且这个Activity已经在当前的Task中运行,系统不再重新创建Activity的实例,而是将在这个Activity上方的所有Activity都关闭,然后调用它的onNewIntent()。
需要注意的是如果该Activity的启动模式是默认的“standard”,那么系统会把它先关闭然后重新启动一个新的实例来接收这个Intent。所以一般会和FLAG_ACTIVITY_SINGLE_TOP一起使用,这样的话就不会关闭已有实例,而是直接把这个Intent投递到当前这个实例的onNewIntent()中。
此外,FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK一起配合使用可以达到“singleTask”的效果。但是,和上面提到的情况一样,还是会有一点不同:如果该Activity的启动模式是默认的“standard”,那么系统会把它先关闭然后重新启动一个新的实例来接收这个Intent.
That's because a new instance isalways created for a new intent when the launch mode is "standard".这是因为系统保证了会为启动模式“standard”的Activity创建一个新的饿实例。
5. FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
如果设置,将在Task的Activitystack中设置一个还原点,当Task恢复时,需要清理Activity。也就是说,下一次Task带着 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记进入前台时(典型的操作是用户在主画面重启它),这个Activity和它之上的都将被销毁(销毁的顺序不是按照出栈顺序,而是反序),以至于用户不能再返回到它们,但是可以回到之前的Activity。
如果stack中多个Activity都被设置了该标志位,那么将会以stack中最底部的那个Activity为准。
这在程序有分割点的时候很有用。例如,一个Email应用程序可能有一个操作是查看一个附件,需要启动图片浏览Activity来显示。这个 Activity应该作为Email应用程序Task的一部分,因为这是用户在这个Task中触发的操作。然而,当用户离开这个Task,然后从主画面选择Email应用,我们可能希望回到查看的会话中,但不是查看图片附件,因为这让人困惑。通过在启动图片浏览时设定这个标志,浏览及其它启动的Activity在下次用户返回到Email程序时都将全部清除。
6. FLAG_ACTIVITY_REORDER_TO_FRONT
如果设置,将使已经存在的Activity移动到stack的顶端,并调用onNewIntent()。
如果FLAG_ACTIVITY_CLEAR_TOP标志也设置的话,那么这个标志将被忽略。
假设当前栈中的内容是A,B,C,D,此时在D中通过该方式启动B,流程如下:
ActivityD: ====>onSaveInstanceState()
ActivityD:====> onPause()
ActivityB: ====> onNewIntent()
ActivityB:====> onRestart()
ActivityB:====> onStart()
ActivityB:====> onResume()
ActivityB:====> onPostResume()
ActivityD:====> onStop()
2. manifest中<activity>的allowTaskReparenting属性
<activity android:name=".ActivityB"
android:label="ActivityB"
android:allowTaskReparenting="true">
</activity>
设置为true的作用是,当在应用A中启动了应用B的ActivityB,之后又通过Home键切出应用A,并启动应用B或者是将已经运行在后台的应用B带到前台,那么:
1. 如果将应用B带到前台,那么系统会将应用A中的所有的ActivityB都从堆栈中抽取出来,然后按照原来的次序放入到应用B的堆栈,然后显示最上面的ActivityB。
2. 如果是启动应用B,那么很惨的是,系统仍然会将之前在应用A中创建的ActivityB从堆栈中抽取出来,并整体放入应用B的堆栈,然后依次出栈destroy:
ActivityB: ====>onDestroy()
ActivityB:HashCode=1078795032 TaskId=129
ActivityB: ====>onDestroy()
ActivityB: HashCode=1078528752TaskId=129
ActivityA: ====> onCreate()
ActivityA: HashCode=1077874256 TaskId=130
ActivityA: <==== onCreate()
ActivityA: ====> onStart()
ActivityA: ====> onPostCreate()
ActivityA: ====> onResume()
ActivityA: ====> onPostResume()
例如,如果Email中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序提供的,但是,现在它作为Email Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当Email Task再次进入前台时,就看不到它了。
需要注意的是,由于启动模式为“singleTask”和 “singleInstance”的Activity只能位于自己的(taskAffinity匹配)task中,因此,重新宿主对它们实际上是不起作用的,因为重新宿主就是重新回到自己所属task(taskAffinity匹配)的怀抱,所以重新宿主实际上只对“standard”和“singleTop”模式有意义。
3. manifest中<activity>的taskAffinity属性
<activity android:name=".ActivityB"
android:label="ActivityB"
android:taskAffinity="">
</activity>
taskAffinity属性指定Activity归属于哪一个task,属性值是字符串。
默认情况,一个应用程序中的所有Activity都拥有相同的affinity,默认值是从应用程序的设定继承下来(<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。
可以通过taskAffinity来重组Activity,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。
拥有相同的affinity的Activity理论上属于相同的Task(在用户的角度是相同的“应用程序”)。Task的affinity是由它的根Activity决定的。
taskAffinity只有当<activity>中的allowTaskReparenting设置为true,或者是调用方将Intent的flag添加FLAG_ACTIVITY_NEW_TASK属性时才会生效。
taskAffinity决定两件事情:
1. 当intent包含FLAG_ACTIVITY_NEW_TASK时,Activity宿主的Task
2. 当<activity>中的TaskReparenting属性设置为"true"时,Activity重新宿主的Task
4. Task中activity stack的维护策略
<activity android:name=".ActivityB"
android:label="ActivityB"
android:alwaysRetainTaskState="true"
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true">
</activity>
一般来说,当用户有一段时间没有访问Task时,例如30分钟,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。但是系统也允许我们通过以下属性来改变系统的默认行为:
1. alwaysRetainTaskState
当设为“true”时,系统会原封不动的保持整个stack。
这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。
2. clearTaskOnLaunch
当这个值为“true”,每次用户重新启动这个Task时,都会从stack中删除位于根Activity之上的所有Activivity,并进入到它的根Activity中。
这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。
3. finishOnTaskLaunch
操作粒度是单个Activity,如果设置为“true”,当用户再次启动它的Task时,会从stack中销毁所对应的Activity。
如果这个特性和allowTaskReparenting都设定为“true”,那么这个特性胜出。Activity的affinity忽略。这个Activity不会重新宿主,而是会销毁。
1. 参考文档
http://1622511.blog.51cto.com/1612511/575080
http://winuxxan.blog.51cto.com/2779763/502523
http://winuxxan.blog.51cto.com/2779763/504047
http://winuxxan.blog.51cto.com/2779763/504835