(目录)

启动模式

1、standard

标准模式是默认的启动模式,每次启动一个Activity,就生成一个Activity实例。一个回退栈中可能存在多个相同Activity实例。

2、singleTop

即在栈的顶部只有一个实例。当要启动的Activity有实例在栈中,并不在栈顶,启动时会生成一个新的实例对象。

3、singleTask

singleTask模式是在 一个singeTask的Activity,在系统创建此对象时会创建一个新的TaskRecord,并将此Activity实例作为Task的根Activity。如果任务中已经有此Activity实例,则只会调用此Activity实例的onNewIntent方法,不会创建新的Activity实例,也不会创建一个新的Task。singleTask的Activity实例只能有一个。

问题1:如果启动的Activity不在栈顶会发生什么

是否会将栈顶的Activity全部清除?

4、singleInstance

与singleTask一样,但是,singleInstance的Activity,在生成的Task中只有一个Activity记录,其他的Activity在存放到新的Task中。即singleInstance的Activity启动的任何Activity都会在其他Task中打开。

  • 启动singleIntance的Activity时,如果此Activity不存在,则生成一个新的Task用来存放此Activity;如果Activity对象已存在,则直接回调其onNewIntent方法
  • 当从singleActivity启动其他Activity时,启动的新Activity将存放到原有的Task中。singleTask的Actviity所在Task,将被移到当前新Activity所在Task之后 示例: Main-A-SingleTopA

启动模式配置

1、manifest配置

manifest配置的规则中singleTask、singleIntance自带清除其上Activity的属性,而使用Intent方式时,需要配合FLAG_ACTIVITY_CLEAR_TOP标记使用。

  • standard
  • singleTop
  • singleTask
  • singleInstance
<activity
    android:name=".activity.MainActivity"
    android:launchMode="singleTask"
    android:screenOrientation="portrait"/>

2、intent配置

intent的配置是通过在设置启动Activity参数Intent的flag变量来实现。可以同时配置多个参数,使用|进行拼接。如FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_CLEAR_TOP

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(xxxx);
  • FLAG_ACTIVITY_SINGLE_TOP
  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP

intent配置优先级高于manifest里的配置;在manifest里配置singleTop、singleTask及singleInstance并不会清除其上的Activity,而使用Intent的方法提供了FLAG_ACTIVITY_CLEAR_TOP标记,可以用来清除目标Activity上的其他Activity。

启动模式实现

基本概念

栈(ActivityStack)

ActivtyStack栈是用来存放Actvity启动记录的工具。每当启动一个Activity时,就会将Activity的记录存放到栈中,处于栈顶的Activity获取焦点,与用户进行交互;当Activity销毁时,会将Activity的记录从栈中移除。

  • 不论进行何种操作,==栈中Activity记录不会进行重排==

任务(TaskRecord)

1. TaskRecord创建

应用被启动时,如果任务管理器没有当前应用的任务实例时,会创建一个新的任务实例。

2. TaskRecord销毁

  • 用户点击返回键将回退栈中所有的Activity清除
  • 用户将任务从最近任务列表中移除
  • 任务长时间处于后台,内存不足,系统将任务从任务列表中清除。==当用户再次返回应用时,只有根Activity的状态会被恢复。==

3. TaskRecord前后台

  • 当任务处于与用户交互时,位于前台
  • 当点击home键返回桌面时,任务处于后台

栈、任务、Activity三者之间的关系

一个应用只有一个回退栈(ActivityStack),一个回退栈中可能有多个任务(TaskRecord),一个任务中可能有多个Activity(ActivityRecord)。

  • 任务(TaskRecord)在栈(ActivityStack)中可以调换顺序
  • Activity(ActivityRecord)在任务中不能调换顺序 image.png

栈管理验证

  1. 同一个任务只有一个回退栈,有多个Task,多个Task属于同一个回退栈。
  2. 当一个应用的页面被另一个应用使用singleTask启动时,此应用页面所在的Task被添加到新的应用上,Task上的所有Activity也被添加到回退栈(而非应用的全部回退栈,将应用的栈添加到新应用后,应用的栈也同时从系统中被移除)。当回退时,将添加的Task内所有Activity退出后,就会再次回到新应用页面。
//android4.4 ActivityStackSupervisor.java
void moveTaskToStack(int taskId, int stackId, boolean toTop){
	//通过taskId从系统中寻找指定的task
	final TaskRecord task = anyTaskForIdLocked(taskId);
	if (task == null) {
		return;
	}
	//获取task所在的栈stack
	final ActivityStack stack = getStack(stackId);
	if (stack == null) {
		Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
		return;
	}
	//将task从栈stack中移除,同时从系统中移除栈stack
	removeTask(task);
	//将task添加到一个新的回退栈stack中
	stack.addTask(task, toTop);
	mWindowManager.addTask(taskId, stackId, toTop);
	//启动顶层的Activity
	resumeTopActivitiesLocked();
}
  1. singleTask为什么会在栈底? 这样从别的应用启动singleTask页面时,只有一个Activity被添加到新应用的回退栈中。