有了任务栈,应用就可以复用本身的Activity,或者是使用其他应用的Activity。
我们先看一下整体的类图,主要是有三个类,ActivityStack,ActivityRecord和TaskRecord。

ActivityStack
ActivityStatck用来管理Activity的任务栈,它的内部有一个枚举类型,记录Activity的状态。
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED,
RESTARTING_PROCESS
}
同时有多个ArrayList,用来存储不同类型的ActivityRecord或TaskRecord列表。
/**
* The back history of all previous (and possibly still
* running) activities. It contains #TaskRecord objects.
*/
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
/**
* List of running activities, sorted by recent usage.
* The first entry in the list is the least recently used.
* It contains HistoryRecord objects.
*/
private final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
TaskRecord
TaskRecord表示Activity的任务栈,用来记录Activity所在任务栈的所有信息,同时它的内部有一个或多个ActivityRecord。
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack;
final int taskId; // Unique identifier for this task.
ActivityRecord
最小的结构单位是ActivityRecord,前面介绍Activity的启动过程中,提到startActivity的时候会创建一个ActivityRecord对象,记录Activity的所有信息,主要的内容如下:
final ActivityInfo info; // all about me
// TODO: This is duplicated state already contained in info.applicationInfo - remove
ApplicationInfo appInfo; // information about activity's app
//……
private TaskRecord task; // the task this is in.
Launch Mode
我们通过Intent启动Activity的时候,通常要指定启动方式。
- standard
默认模式,每次启动Activity都会创建一个新的Activity实例。 - singleTop
如果Activity已经在栈顶,就不会创建新的Activity实例,而是调用原有Activity的onNewIntent方法,否则创建新的Activity实例。 - singleTask
如果Activity已经在归属的栈中,就将该栈中Activity上的所有其他Activity出栈,同时调用它的onNewIntent方法;
如果归属的栈中没有Activity,就创建新的实例,入栈;
如果栈不存在,就创建新的任务栈,创建新的Activity实例,入栈。
有些博客认为singleTask一定会创建新的任务栈,其实是不对的。正常的流程应该是:
(1)启动activity时发现启动模式为singleTask,那么设定它的启动标志为FLAG_ACTIVITY_NEW_TASK;
(2)获得它的taskAffinity
(3)检查是否已经存在一个affinity相同的任务
(4)如果任务栈存在,判断栈中是否存在该activity,将该activity上面的实例出栈,调用它的onNewIntent方法
(5)如果activity不存在,就创建实例,入栈
(6)如果任务栈不存在,就创建任务栈和实例 - singleInstance
每次启动Activity确保栈中只有一个Activity实例。
简单理解一下,
standard是每次都会创建新的Activity实例,但是会跟之前保持同一个栈;
singleTop是当Activity已经在栈顶,就不会创建新的实例,而是调用onNewIntent方法;
singleTask是当Activity已经存在栈中,不管是否在栈顶,都调用onNewIntent方法,不会创建新的实例,并且会将该Activity之前的Activity都出栈;
singleInstance是确保栈中只有一个Activity实例,如果栈不存在就创建新的栈,如果该栈存在,则调用onNewIntent方法。
我们通过adb命令看一下
adb shell dumpsys activity activities
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #16: type=standard mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #1958
//……
Running activities (most recent first):
TaskRecord{4a3f612 #1958 A=com.example.zgone.calculator U=0 StackId=16 sz=3 mode=1}
Run #2: ActivityRecord{54b2a75 u0 com.example.zgone.calculator/.MainActivity t1958}
Run #1: ActivityRecord{cb68a4d u0 com.example.zgone.calculator/.SecondActivity t1958}
Run #0: ActivityRecord{5102efd u0 com.example.zgone.calculator/.MainActivity t1958}
mResumedActivity: ActivityRecord{54b2a75 u0 com.example.zgone.calculator/.MainActivity t1958}
mLastPausedActivity: ActivityRecord{cb68a4d u0 com.example.zgone.calculator/.SecondActivity t1958}
该任务栈有三个ActivityRecord,栈顶是MainActivity。
Intent的Flag
除了在AndroidManifest中指定Launch Mode,也可以在start Activity的时候指定Intent的Flag。
1.FLAG_ACTIVITY_NEW_TASK
很多博客说这个标志跟singleTask是一样的效果,需要创建新的栈,但实际上只有在两个应用间切换的时候才是这样,如果是同个应用内部,因为taskAffinity相同,效果类似standard。
这个标志更常用的场景应该是在service中启动Activity的时候,如果使用的Context不是Activity的Context,就需要指定FLAG_ACTIVITY_NEW_TASK,否则将会出现异常crash。因为默认的启动模式是standard,这种模式会将Activity归入当前所在的任务栈,而Application Context或者Service的context是不包含任务栈的。
2.FLAG_ACTIVITY_SINGLE_TOP
功能类似singleTop
3.FLAG_ACTIVITY_CLEAR_TOP
功能类似singleTask,会将该目标Activity之前的Activity都出栈,区别是它并不是调用onNewIntent方法,而是oCreate。
taskAffinity
因为默认情况下,一个Android应用所有Activity都有一样的taskAffinity,所以这个地方容易被忽略。比如之前的FLAG_ACTIVITY_NEW_TASK,只有在两个Activity的taskAffinity不一致的情况下,才会创建新的栈。
也就是说,taskAffinity需要配合NEW_TASK标志使用才能生效。
参考
https://www.jianshu.com/p/94816e52cd77
https://blog.csdn.net/zhangjg_blog/article/details/10923643
网友评论