基于Android 9.0的源码剖析, 分析Android Activity启动流程;Android的管理主要是通过Activity栈来进行的。当一个Activity启动时,系统根据其配置或调用的方式,将Activity压入一个特定的栈中,系统处 于运行(Running or Resumed)状态。当按Back键或触发finish()方法时,Activity会从栈中被压出,进而被销毁,当有新的Activity压入栈时, 如果原Activity仍然可见,则原Activity的状态将转变为暂停(Paused)状态,如果原Activity完全被遮挡,那么其状态将转变为 停止(Stopped)。
Android系统中的每一个Activity都位于一个Task中。一个Task可以包含多个Activity,同一个Activity也可能有多个实例。 在AndroidManifest.xml中,我们可以通过android:launchMode来控制Activity在Task中的实例。
Activity启动模式就是属于Activity配置属性之一,叫它具有四种启动模式,分别是:1.standard ,2.singleTop,3.singleTask,4.singleInstance,一般如果不显示声明,默认为standard模式。launchMode 在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他 Activity实例公用一个task里。
standard模式:这是系统默认的启动模式,这种模式就是创建一个Activity压入Task容器栈中,当当前Activity激活,并处在和用户交互时,此Activity弹出栈顶,当finish()时候,在任务栈中销毁该实例。
singleTop模式:这种模式首先会判断要激活的Activity是否在栈顶,如果在则不重新创建新的实例,复用当前的实例,如果不在栈顶,则在任务栈中创建实例。条件是是否在栈顶,而不是是否在栈中。
singleTask模式: 这种模式启 动的目标Activity实例如果已经存在task容器栈中,不管当前实例处于栈的任何位置,是栈顶也好,栈底也好,还是处于栈中间,只要目标 Activity实例处于task容器栈中,都可以重用该Activity实例对象,然后,把处于该Activity实例对象上面全部Activity实 例清除掉,并且,task容器栈中永远只有唯一实例对象,不会存在两个相同的实例对象。所以,如果你想你的应用不管怎么启动目标Activity,都只有 唯一一个实例对象,就使用这种启动模式。
singleInstance模式:当该模式Activity实例在任务栈中创建后,只要该实例还在任务栈中,即只要激活的是该类型的Activity,都会通过调用实例的newInstance()方法重用该Activity,此时使用的都是同一个Activity实例,它都会处于任务栈的栈顶。此模式一般用于加载较慢的,比较耗性能且不需要每次都重新创建的Activity。
Back栈管理了当你在Activity上点击Back键,当前Activity销毁后应该跳转到哪一个Activity的逻辑。
其实在ActivityManagerService与WindowManagerService内部管理中,在Task之外,还有一层容器,这个容器应用开发者和用户可能都不会感觉到或者用到,但它却非常重要,那就是ActivityStack。 下文中,我们将看到,Android系统中的多窗口管理,就是建立在Stack的数据结构上的。 一个ActivityStack中包含了多个TaskRecord,一个TaskRecord中包含了多个ActivityRecord,下图描述了它们的关系:
另外还有一点需要注意的是,ActivityManagerService和WindowManagerService中的Task和Stack结构是一一对应的,对应关系对于如下:
ActivityStack <–> TaskStack
TaskRecord <–> Task
即,ActivityManagerService中的每一个ActivityStack或者TaskRecord在WindowManagerService中都有对应的TaskStack和Task,这两类对象都有唯一的id(id是int类型),它们通过id进行关联。
Instrumentation
用于实现应用程序测试代码的基类。当在打开仪器的情况下运行时,这个类将在任何应用程序代码之前为您实例化,允许您监视系统与应用程序的所有交互。可以通过AndroidManifest.xml的标签描述该类的实现。
ActivityManager
该类提供与Activity、Service和Process相关的信息以及交互方法, 可以被看作是ActivityManagerService的辅助类。
ActivityManagerService
Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。
ActivityThread
管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作。
ActivityStack
负责单个Activity栈的状态和管理。
ActivityStackSupervisor
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
ClientLifecycleManager
用来管理多个客户端生命周期执行请求的管理类。
Activity
用来管理客户端视图、点击、输入等功能的抽象,具有完整的生命周期
ViewRootImpl
APP进程与system_server进程进行视图相关通信的桥梁,同时也管理着APP进程视图方面操作的主要逻辑
ActivityRecord
Activity的信息记录在ActivityRecord对象, 并通过通过成员变量task指向TaskRecord
ProcessRecord app //跑在哪个进程
TaskRecord task //跑在哪个task
ActivityInfo info // Activity信息
ActivityState state //Activity状态
ApplicationInfo appInfo //跑在哪个app
ComponentName realActivity //组件名
String packageName //包名
String processName //进程名
int launchMode //启动模式
int userId // 该Activity运行在哪个用户id
ActivityState:
INITIALIZING
RESUMED:已恢复
PAUSING
PAUSED:已暂停
STOPPING
STOPPED:已停止
FINISHING
DESTROYING
DESTROYED:已销毁
TaskRecord
Task的信息记录在TaskRecord对象.
ActivityStack stack; //当前所属的stack
ArrayListmActivities;; // 当前task的所有Activity列表
int taskId
String affinity; 是指root activity的affinity,即该Task中第一个Activity;
int mCallingUid;
String mCallingPackage; //调用者的包名
ActivityStack
ArrayListmTaskHistory //保存所有的Task列表
final int mStackId;
int mDisplayId;
ActivityRecord mPausingActivity //正在pause
ActivityRecord mLastPausedActivity
ActivityRecord mResumedActivity //已经resumed
ActivityRecord mLastStartedActivity
所有前台stack的mResumedActivity的state == RESUMED, 则表示allResumedActivitiesComplete, 此时mLastFocusedStack = mFocusedStack;
ActivityStackSupervisor
ActivityStack mHomeStack //桌面的stack
ActivityStack mFocusedStack //当前聚焦stack
ActivityStack mLastFocusedStack //正在切换
SparseArray mActivityDisplays //displayId为key
SparseArray mActivityContainers // mStackId为key
1、点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
2、system_server进程接收到请求后,向zygote进程发送创建进程的请求;
3、Zygote进程fork出新的子进程,即App进程;
4、App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
5、system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
6、App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
7、主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。