App程序中有很多Activity、你可以通俗的理解为把一个Activity看做是一个UI界面。在Andord系统中Activity是以堆栈<堆栈的特性:只有压入和弹出 先进后出>的形式存在。堆栈中的根Activity就是应用程序的启动Activity。而堆栈中最上方的Activity则是当前运行的/用户正在操作的UI Activity。
也可以这样去理解:堆栈中保存的是Activity对象,如果一个应用中多次使用了一个Activity,那么就会使同一个任务中出现多个该Activity的对象。一个程序在运行、他所启动的Activity通常情况下<注意是通常情况下>在同一个堆栈中、这个也叫做任务栈
Activity和Task的关联: Activity在任务中的行为,受控于启动Activity的行为对象的标志位和清单文件中的
主要的行为标志有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
..............等
主要的
launchMode
taskAffinity
allowTaskReparenting
alwaysRetainTaskState
clearTaskOnLaunch
finishOnTaskLaunch
下面将对每一个属性和标志一一介绍:
[虽然全是文字说明,稍有枯味、但只要你细细消化 相信使你对Activity栈的管理会进一步理解]
1、launchMode:Activity 4种启动模式
1>、standard: <默认启动模式>
在任务栈中总是创建一个新的Activity实例
2>、singleTop:
在任务栈中如果有存在一个和新启动Activity相同的Activity正在栈顶则不再创建一个新的Activity,即不再调 用onCreate(),而是通过调用onNewIntent()方法。如果不存在栈顶,这时候就和standard一样创建一个新的 Activity实例,走onCreate()方法。
3>、singleTask:
①设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性 值taskAffinity的Task存在;如果存在这样的Task,它就会在这个Task中启动,否则就会在新的任务栈中启动。 因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。
② 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经 存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity 实例会位于任务的Stack顶端中。
③ 在一个任务栈中只有一个”singleTask”启动模式的Activity存在。他的上面可以有其他的Activity。这点与singleInstance是有区别的。
4>、singleInstance:
在一个新的任务栈中启动,且该栈中有且只有他一个Activity实例、不允许有其他的Activity成员存在。
永远他一个。
2、android:taskAffinity: task亲和力
通常来说一个程序内/任务栈中的Activity具有亲和力,也就是说具有相同亲和力的Activity默认属于同一个任务Task中,
affinity决定两件事情——Activity重新宿主(从一个Task跳到了另一个Task中,新的Task就被称为重新宿主)的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。
默认情况,一个应用程序中的所有Activity都拥有相同的affinity。你可以通过设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。如果不指定改activity到底属于哪个task,则可以将affinity设置为空字符串。如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考
注意:affinity只有在加载activity的Intent对象包含了FLAG_ACTIVITY_NEW_TASK 标记,或者当activity的allowTaskReparenting属性设置为“true”时才有效。
3、android:allowTaskReparenting:是否允许Activity跳转/更改Task
用来标记Activity能否从启动的Task移动到有着相同affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时的那个Task里。如果这个特性没有被设定,设定到
4、android:alwaysRetainTaskState:当按下Home主键将程序退回至后台运行,再回到前台时是否保留Task状态
用来标记Activity所在的Task的状态是否总是由系统来保持——“true”,表示总是;“false”,表示在某种情形下允许系统恢复Task到它的初始化状态。默认值是“false”。这个特性只针对Task的根Activity有意义;对其它Activity来说,忽略之。
一般来说,特定的情形如当用户从主画面重新选择这个Task时,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。典型的情况,当用户有一段时间没有访问这个Task时也会这么做,例如30分钟。
然而,当这个特性设为“true”时,用户总是能回到这个Task的最新状态,无论他们是如何启动的。这非常有用,例如,像Browser应用程序,这里有很多的状态(例如多个打开的Tab),用户不想丢失这些状态。系统会为我们保持这些状态数据。5、android:clearTaskOnLaunch:当按下Home主键将程序退回至后台运行,再回到前台时是否清除/移除除了跟Activity<启动Activity>之外的所有Activity。
用来标记是否从Task中清除所有的Activity,除了根Activity外(每当从主画面重新启动时)——“true”,表示总是清除至它的根Activity,“false”表示不。默认值是“false”。这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。
当这个值为“true”,每次用户重新启动这个Task时,都会进入到它的根Activity中,不管这个Task最后在做些什么,也不管用户是使用BACK还是HOME离开的。当这个值为“false”时,可能会在一些情形下(参考alwaysRetainTaskState特性)清除Task的Activity,但不总是。
假设,某人从主画面启动了ActivityP,并从那里迁移至Activity Q。接下来用户按下HOME,然后返回Activity P。一般,用户可能见到的是Activity Q,因为它是P的Task中最后工作的内容。然而,如果P设定这个特性为“true”,当用户按下HOME并使这个Task再次进入前台时,其上的所有的Activity(在这里是Q)都将被清除。因此,当返回到这个Task时,用户只能看到P。如果这个特性和allowTaskReparenting都设定为“true”,那些能重新宿主的Activity会移动到共享affinity的Task中;剩下的Activity都将被抛弃。
6、android:finishOnTaskLaunch:当按下Home主键将程序退回至后台运行,再回到前台时是否关闭/结束掉退回到后台之前的Activity.
用来标记当用户再次启动它的Task(在主画面选择这个Task)时已经存在的Activity实例是否要关闭(结束)——“true”,表示应该关闭,“false”表示不关闭。默认值是“false”。
如果这个特性和allowTaskReparenting都设定为“true”,这个特性胜出,Activity的affinity忽略。这个Activity不会重新宿主,但是会销毁。
通过Intent设置的属性标识:
形式如下:Intent intent = new Intent(SwitchActivity.this, ThredActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
在默认情况下,一个新Activity被另一个Activity调用了startActivity()方法,载入任务之中。并压入了调用者所在的堆栈。然而,如果传递给startActivity()的Intent对象包含了FLAG_ACTIVITY_NEW_TASK标记,系统会为新Activity安排另外一个任务。一般情况下,如同标记所暗示的那样,这会是一个新任务。然而,这并不是必然的。如果已经存在了一个与新Activity有着同样affinity的任务,则Activity会载入那个任务之中。如果没有,则启用新任务。
简言之:有相同affinity的任务,则压入该任务,否则创建一个新的任务。
2、FLAG_ACTIVITY_CLEAR_TOP
如果intent将要启动的Activity已经存在于一个Task中,那么这个Task中该Activity上面的那些Activity都会被移除销毁,然后这个intent将会作为一个新的intent投递给目标Activity(目标Activity已经位于栈的顶端了)。
这个启动模式还可以与FLAG_ACTIVITY_NEW_TASK结合起来使用:用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,然后清除它直到根Activity。这非常有用,例如,当从NotificationManager处启动一个Activity3、FLAG_ACTIVITY_SINGLE_TOP
如果设置,当这个Activity位于历史stack的顶端运行时,不再启动一个新的。
同 android: launchMode = “singleTop”
4、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果设置,新的Activity不会在最近启动的Activity的列表中保存。
以上只介绍了常有用的几种控制Activity跳转的Flag标识
更多详细前往 http://android.toolib.net/reference/android/content/Intent.html 进行学习。