一、Task与返回栈。
Task是指一系列的Activity,这些Activity按照各自的打开顺序排列在堆栈(返回栈)中。
按返回键可以从返回栈中弹出响应的Activity,直到返回主屏幕为止。当所有Activity都从堆栈中移除之后,任务就不复存在了。
当切换应用时,或者切换到主屏幕,Task都会切换到后台,如果再切回应用,则Task切回前台。但是如果后台同时运行多个Task,系统可能会销毁后台的Activity,以回收内存,导致Activity状态丢失。
Activity和任务的默认行为总结如下:
1.当ActivityA启动ActivityB时,ActivityA将会停止,但系统会保留其状态(如,滚动位置和EditText的输入文本)。如果在ActivityB按返回键,则ActivityA恢复其状态,继续执行;
2.按Home键离开任务时,当前Activity停止且其Task进入后台。系统将保留每个Task中每个Activity的状态。如果用户稍后切回Task,则任务将出现在前台并恢复执行栈顶Activity;
3.按返回键,当前Activity从栈中弹出并销毁,前一个Activity恢复执行。销毁Activity时,系统不会像切换到后台那样保留其状态;
4.Activity默认可以多次实例化。
二、保留Activity状态。
当系统停止一个Activity时,如果需要回收系统资源,则会完全销毁该Activity,则其状态信息都将会丢失。但是系统仍会知道该Activity存在于返回栈中,但是当Activity被置于栈顶时,系统会重建(而不是恢复Activity)。为了避免必要状态信息丢失,应当主动在Activity中实现onSaveInstanceState()方法来保留工作。
三、启动模式。
两种方式:
清单指定:在Manifest中<activity>中使用launchMode指定。
使用Intent标志:startActivity()时,在Intent中加入一个标志,用于声明新Activity如何(或是否)与当前任务相关联。
launchMode:
standard:默认模式。每次启动都重新创建。Task可以拥有多个实例,每个实例也可以属于不同Task。
singleTop:如果当前Task顶部已经存在该Activity的实例,则系统会调用该实例的onNewIntent()方法启动它,而不是创建新的实例。Task可以拥有多个实例,每个实例也可以属于不同Task(前提是该Task不在栈顶)。
注意:为Activity 创建新实例时,按“返回”按钮返回到前一个 Activity。 但当 Activity 的现有实例处理新 Intent 时,新 Intent 到达 onNewIntent() 之前,无法按“返回”按钮返回到 Activity 的状态。
singleTask:系统创建新Task并实例化位于新任务底部的Activity。但如果该实例已经存在于一个单独的Task中,则系统会调用现有实例的onNewIntent()方法启动它,而不是创建新实例。一次只能存在Activity的一个实例。
注意:尽管Activity在新Task中启动,但是按返回键仍会返回到前一个Activity。
singleInstance:与singleTask相同,但是系统不会将任何其他的Activity启动到包含该实例的Task中。该Activity是其Task中唯一仅有的成员,由此Activity启动的任何Activity均在单独的Task中打开。
Inten标志:
FLAG_ACTIVITY_NEW_TASK:与singleTask相同;
FLAG_ACTIVITY_SIGLE_TOP:与singleTop相同;
FLAG_ACTIVITY_CLEAR_TOP:如果启动的Activity在当前任务中运行,则会销毁当前Task栈中顶部所有Activity,并通过onNewIntent()启动该实例,而不是新建。没有launchMode与之对应。FLAG_ACTIVITY_CLEAR_TOP常与FLAG_ACTIVITY_NEW_TASK结合使用,可以找到其他Task栈中的现有Activity,并将其放入可以从中响应Intent的位置。如果指定Activity的启动模式为standard,则该Activity也会从栈中移除,并在其位置启动一个新实例。因为当启动模式为standard时,将始终为新Intent创建新实例。
四、关联
关联是指Activity优先属于哪个任务。同一应用中的所有Activity默认是彼此关联的,则默认同意应用中的所有Activity优先位于相同的任务中。可以通过<activity>中的taskAffinity属性修改Activity的关联。taskAffinity取字符串,且必须不同于<manifest>中声明的默认包名,因为该默认包名是应用的默认任务关联。
关联必须在以下两种情况下才会起作用:
1.启动的Intent包含FLAG_ACTIVITY_NEW_TASK标志,如上文,其原本就会开启新的任务(但未强制是哪一个)来启动,taskAffinity属性则指定了其关联的任务。
2.Activity将其allowTaskReparenting属性设置为true,这种情况下,Activity可以从启动的任务移动到其关联的任务。
五、清理返回栈
用户长时间离开Task,系统会清除所有Activity的任务,根Activity除外。
设置alwaysRetainTaskState为true,可以使很长时间后Task仍然保留所有Activity。
clearTaskOnLaunch为true,当用户离开Task并返回时,系统会清除除了根Activity以外所有的Activity。
finishOnTaskLaunch为true,针对单个Activity,与clearTaskOnLaunch类似。