概述
Activty是四大组件之首,重要性不言而喻。这篇笔记整理于寒假实习期间,大致总结Activity的启动流程,由于整个启动过程实在太绕,调用链太长,暂时没有完整分析一遍,空缺的看需要再补充。分析过程以API-26为基础。
几个基础对象
- ActivityManagerService:简称AMS,服务端对象,负责系统中的所有Activity的生命周期。
- ActivityThread:App的真正入口。当开启App之后,会调用main()开始执行,开启消息循环队列,这就是传说中的UI线程或者说主线程。与AMS配合一起完成Activity的管理。
- ApplicationThread:用来实现AMS与ActivityThread之间的交互。在AMS需要管理相关Application中的Activity的生命周期的时候,通过Application Thread的代理对象与Activity Thread通讯。
- ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理和ActivityThread通讯的。
- Instrumentation:每个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
- Activity Stack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系、状态信息等。
- ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,用来记录Activity的状态及其他管理信息。其实就是服务端的Activity对象的映像。
- TaskRecord:AMS抽象出来的一个“任务”的概念。是记录ActivityRecord的栈。一个Task包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。
http://duanqz.github.io/2016-02-01-Activity-Maintenance#activityrecord
ActivityRecord:
ActivityRecord是AMS调度Activity的基本单位。它需要记录AndroidManifest.xml中定义的Activity的静态特征。同时也需要记录Activity在被调度时的变化。其内部的属性比较多:
每次启动一个新的Activity时都会创建一个ActivityRecord对象。
TaskRecord:
TaskRecord的职责是管理多个ActivityRecord。所谓的任务、任务栈指的就是TaskRecord。启动Activity时需要找到Activity的宿主任务,如果不存在,则需要创建一个,也就是说所有的ActivityRecord都必须有宿主。TaskRecord与ActivityRecord是一对多的关系。TaskRecord中包含了ActivityRecord的数组。同时TaskRecord还需要维护任务栈本身的状态。其内部的属性如下:
在TaskRecord中提供了一系列方法用于管理任务栈:
ActivityStack:
从名字上看感觉它才是真正的栈,实际上它是一个manager的角色,负责管理协调ActivityRecord和TaskRecord。
总结就是,ActivityRecord是对应每个Activity,TaskRecord是对应每个任务栈,ActivityStack是用于管理协调ActivityRecord和TaskRecord的角色
Activity启动过程
调用startActivity方法,最终都会调用startActivityForResult方法。在startActivityForResult方法内部,又会调用Instrumentation中的execStartActivity方法。而在execStartActivity内部,又会通过ActivityManagerNative来实现。ActivityManagerNative继承自Binder,实现了IActivityManager接口,是一个抽象类。ActivityManagerNative的实现类是AMS。
ActivityManagerNative中的getDefault:
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
Singleton是一个封装的单例,这里通过单例对外提供ActivityMangerNative的实例。在第一次调用时,会通过ServiceManager.getService方法拿到AMS的代理对象。
在拿到AMS的代理对象后,就可以调用它的startActivity方法来启动Activity,而在AMS的startActivity内部,会调用startActivityAsUser方法:
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}
从startActivityAsUser方法可以看出,启动过程又转移到了ActivtyStarter的startActivityMayWait方法中继续进行(在《Android开发艺术探索》中说是ActivityStackSupervisor,可能是SDK版本不同)。ActivityStarter类是负责处理Activity的Intent和Flags的逻辑,还有管理Stack和TaskRecord的。。在这个方法内部会调用ActivityStack的topRunningActivitiesLocked方法,。
启动流程太长了,写不下去了,下次有精力再继续。根据Activity的生命周期大致可以猜测,会判断Activity的启动模式与FLAG,决定是否需要创建ActivityRecord与TaskRecord,然后将之前的Activity暂停,再回调新的Activity的onCreate方法。
18.01.25补,大致流程图如下:
流程图有几点解释:
1. ActivityStarter:
/**
* Controller for interpreting how and then launching activities.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
```
从官方注释可以知道ActivityStarter主要解释了怎样启动一个Activity。这里说的“how”,包括设置ActivityRecord、TaskRecord等信息。
2. ActivityStackSupervisor:主要用于管理ActivityStack中的信息。
3. ActivityStack:要注意的ActivityStack并不是任务栈,任务栈的真正实现是TaskRecord,ActivityStack是管理协调管理TaskRecord、ActivityRecord的类。
4. ActivityStarter:
* startActivityMayWait:根据Intent获取到Activity的启动信息(ResolveInfo和ActivtyInfo),获取到调用者的PID和UID。
* startActivityLocked:创建ActivityRecod,含有Activity的核心信息。
* startActivityUnchecked:根据启动的FLAG信息,设置TaskRecord。
5. 核心是ActivityStack#resumeTopActivityInnerLocked方法:根据ActivityRecord和ActivityOptions完成Activity的切换,移至栈顶。
6. ActivityStackSupervisor#realStartActivityLocked方法:含有启动的核心方法scheduleLaunchActivity,即调用IApplicationThread的scheduleLaunchActivity方法。
-----
在启动完Activity之后,回到Instrucmentation中的execStartActivity里,接着会执行checkStartActivityResult方法:
```java
/** @hide */
public static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startVoiceActivity does not match active session");
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
在这方法内部,通过启动的结果,判断是否正常启动,如果没有正常启动,抛出相应的异常。
双方跨进程通信
- 在client端,是通过ActivityManager来获取到AMS的单例对象,是一个AMS的代理对象,在之前的版本中对应的是ActivityManagerProxy(ActivityManagerNative内部类)。
- 在AMS进程中,是通过client端传过来的IApplicationThread对象(ApplicationThread)的代理对象(通过attachApplication(IApplication thread)方法),来实现与client端通信的。
如下图:
零散知识点
- App与AMS通过Binder进行IPC,而AMS(SystemServer进程)与Zygote通过Socket进行IPC。
- 在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体完成。
总结
关于Activity的启动过程还有很多点可以深入,比如AMS进程与App进程通信的具体过程、在ActivityStackSupervisor、ActivityStack中到底是怎样处理Activity信息的等等,还很多要学的。
https://juejin.im/entry/57a06455a633bd00601394e0
http://blog.csdn.net/zhaokaiqiang1992/article/details/49428287#%E5%89%8D%E8%A8%80
http://blog.csdn.net/singwhatiwanna/article/details/18154335
http://dev.dafan.info/detail/252012?p= 探索7.x, 全面解析Activity启动框架 (1)
http://www.heqiangfly.com/2016/04/08/android-source-code-analysis-ams-app-ipc/ Android AMS 与 APP 进程通信
http://www.heqiangfly.com/2016/04/10/android-source-code-analysis-activity-start-process/ Android startActivity 流程分析