不同启动流程
根据启动流程分为三种
- 通过Launcher点击app创建新进程,称为 根Activity组件的启动流程
- 点击app后进入app,在app中的startActivity操作,称之为 子Activity组件在进程内的启动流程
- 在app中,可能出现跳转到其他进程的app的Activity,称之为 子Activity组件在新进程中的启动流程
类结构
ProcessRecord
ProcessRecord(进程数据类)
文件位于 \frameworks\base\services\core\java\com\android\server\am 中
记录一个进程中的信息
ActivityRecord
ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息
TaskRecord
TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序
ActivityStack
ActivityStack是一个管理类,用来管理系统所有Activity的各种状态,其内部维护了TaskRecord的列表,因此从Activity任务栈这一角度来说,ActivityStack也可以理解为Activity堆栈。它由ActivityStackSupervisor来进行管理的,而ActivityStackSupervisor在AMS中的构造方法中被创建。
ActivityThread
ActivityThread,App的真正入口,主线程
系统每当启动一个应用程序进程时,都会加载一个ActivityThread,并保存在Activity类的成员变量 mMainThread
ApplicationThread
ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
ApplicationThreadProxy
ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的
Instrumentation
Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作
对应代码:
public ActivityManagerService(Context systemContext) {
...
mStackSupervisor = new ActivityStackSupervisor(this);
...
}
ActivityStarter
ActivityStarter是Android 7.0新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联
AMS中的重要调度相关变量
ActivityStack的实例类型
ActivityStackSupervisor中有多种ActivityStack实例
public final class ActivityStackSupervisor implements DisplayListener {
...
ActivityStack mHomeStack;
ActivityStack mFocusedStack;
private ActivityStack mLastFocusedStack;
...
}
● mHomeStack用来存储Launcher App的所有Activity
● mFocusedStack表示当前正在接收输入或启动下一个Activity的所有Activity
● mLastFocusedStack表示此前接收输入的所有Activity
ActivityState
ActivityStack中通过枚举存储了Activity的所有的状态
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
特殊状态的Activity
● ActivityRecord mPausingActivity = null;//正在暂停的Activity
● ActivityRecord mLastPausedActivity = null;//上一个已经暂停的Activity
● ActivityRecord mLastNoHistoryActivity = null;//最近一次没有历史记录的Activity
● ActivityRecord mResumedActivity = null;//已经Resume的Activity
● ActivityRecord mLastStartedActivity = null;//最近一次启动的Activity
● ActivityRecord mTranslucentActivityWaiting = null;//传递给convertToTranslucent方法的最上层的Activity
维护的 ArrayList
ActivityStack中维护了很多ArrayList,这些ArrayList中的元素类型主要有ActivityRecord和TaskRecord,其中TaskRecord用来记录Activity的Task
ArrayList<TaskRecord> mTaskHistory = new ArrayList<>()
最为重要的内部变量,保存了所有正在运行的Activity. TaskRecord 中保存有ActivityRecord
ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>()
基于LRU算法的最近使用的Activity列表
ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>()
不考虑转换动画的Activity
ActivityStarter中的 ArrayList
ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>()
当AMS内部没有准备好时,如果客户进程请求启动某个Activity,那么会暂时被保存到该变量中
这种情况一般发生于系统启动时
Activity栈概念
从Activity任务栈的角度来说,一个或多个ActivityRecord会组成一个TaskRecord,TaskRecord用来记录Activity的栈,而ActivityStack包含了一个或多个TaskRecord
Launch Mode
● standerd:默认模式,每次启动Activity都会创建一个新的Activity实例
● singleTop:如果要启动的Activity已经在栈顶,则不会重新创建Activity,同时该Activity的onNewIntent方法会被调用。如果要启动的Activity不在栈顶,则会重新创建该Activity的实例
● singleTask:
○ 如果要启动的Activity已经存在于它想要归属的栈中,那么不会创建该Activity实例,将栈中位于该Activity之上的所有的Activity出栈,同时该Activity的onNewIntent方法会被调用
○ 如果要启动的Activity不存在于它想要归属的栈中,并且该栈存在,则会重新创建该Activity的实例
○ 如果要启动的Activity想要归属的栈不存在,则首先要创建一个新栈,然后创建该Activity实例并压入到新栈中
● singleInstance:和singleTask基本类似,不同的是启动Activity时,首先要创建在一个新栈,然后创建该Activity实例并压入新栈中,新栈中只会存在这一个Activity实例
Intent的FLAG
● FLAG_ACTIVITY_SINGLE_TOP:和Launch Mode中的singleTop效果是一样的。
● FLAG_ACTIVITY_NEW_TASK:和Launch Mode中的singleTask效果是一样的。
● FLAG_ACTIVITY_CLEAR_TOP:Launch Mode中没有与此对应的模式,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity出栈。singleTask默认具有此标记位的效果
● FLAG_ACTIVITY_NO_HISTORY:Activity一旦退出,就不会存在于栈中。同样的,也可以在AndroidManifest.xml中设置“android:noHistory”。
● FLAG_ACTIVITY_MULTIPLE_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,系统会启动一个新的栈来容纳新启动的Activity.
● FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:Activity不会被放入到“最近启动的Activity”列表中。
● FLAG_ACTIVITY_BROUGHT_TO_FRONT:这个标志位通常不是由应用程序中的代码设置的,而是Launch Mode为singleTask时,由系统自动加上的。
● FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY:这个标志位通常不是由应用程序中的代码设置的,而是从历史记录中启动的(长按Home键调出)。
● FLAG_ACTIVITY_CLEAR_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,用于清除与启动的Activity相关栈的所有其他Activity
taskAffinity
我们可以在AndroidManifest.xml设置android:taskAffinity,用来指定Activity希望归属的栈, 默认情况下,同一个应用程序的所有的Activity都有着相同的taskAffinity
taskAffinity在下面两种情况时会产生效果
● taskAffinity与FLAG_ACTIVITY_NEW_TASK或者singleTask配合。如果新启动Activity的taskAffinity和栈的taskAffinity相同(栈的taskAffinity取决于根Activity的taskAffinity)则加入到该栈中。如果不同,就会创建新栈
● taskAffinity与allowTaskReparenting配合。如果allowTaskReparenting为true,说明Activity具有转移的能力。拿此前的邮件为例,当社交应用启动了发送邮件的Activity,此时发送邮件的Activity是和社交应用处于同一个栈中。如果发送邮件的Activity的allowTaskReparenting设置为true,此后邮件程序所在的栈位于前台,这个时候发送邮件的Activity就会由社交应用的栈中转移到与它更亲近的邮件程序(taskAffinity相同)所在的栈中。











网友评论