之前介绍了Android IPC通信机制 Binder,接下来开始梳理Activity启动流程。
常见的Activity的启动有两种方式:
- 通过LaunchActivity启动一个应用,启动Activity。
- 通过同一个进程内的startActivity。
以下是基于Android 28的源码进行分析,顺便说一个AS很好用的快捷键:ctrl+shift+N 搜索打开文件
在接下来的流程中重要的几个类:
-
Instrumentation:每个应用程序都有一个Instrumentation,每个Actviity持有它的引用,ActivityThread要创建或暂停Activity时,都是通过Instrumentation进行操作。
-
ActivityManagerService:SystemServer中启动的独立进程,负责管理四大组件,可以利用binder跟它通信
-
ActivityStarter:负责处理intenth和flags、选择启动的task、复用Activity等逻辑。
-
ActivityRecord:每个Activity在AMS中对应一个ActivityRecod,记录Acitivty的信息
-
TaskRecord:就是我们所讲的任务栈,先进后出,存储ActivityRecord
-
ActivityStack:用来管理TaskRecord,ActivityStack是由ActivityStackSupervisor创建的
-
ActivityStackSupervisor:AMS通过ActivityStackSupervisor负责操作ActivityStack
-
ApplicationThread:ActivityThread的内部类,是一个binder对象,是ActivityManagerService向ActivityThread通信的桥梁。
-
ActivityThread:表示APP的主线程,有main函数,
-
ClientLifecycleManager:调用ClientTransaction,让AMS切换到APP进程执行生命周期
从进程的角度分析,可以把Activity的启动流程分成三个阶段:
-
LauncherActivity或原活动的Activity进程
-
AMS进程,真正启动Activity
-
.从AMS到ApplicationThread所在的目标Activity进程,可能跟原活动的Activity进程同一个或者不同进程
1. LauncherActivity或原活动的Activity进程
一般我们从Activity的startActivity()或者Context的startActivity(),之所以把他们分开看,是在Android 28有一些不一样,但最后的走向是一样的。
先看下Context.startActivity(),其中Context的实现是在ContextImpl;
// ContextImpl
public void startActivity(Intent intent) {
warnIfCallingFromSystemProcess();
startActivity(intent, null);
}
public void startActivity(Intent intent, Bundle options) {
...
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
其中mMainThread是ActivityThread,最后转化到Instrumentation.execStartActivity()来启动Activity。
再看一下Activity的startActivity(),其实都是走到了startActivityForResult(),其中requestCode是-1;
// Activity
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
// mParent代表ActivityGroup,已经被废弃
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
...
}
可见最后还是通过Instrumentation的execStartActivity()启动Activity。
mMainThread是ActivityThread,mMainThread.getApplicationThread()是ActivityThread的内部类ApplicationThread,他是一个IBinder。主要用于ActivityThread与AMS的通信。
// Instrumentation
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
...
}
// ActivityManager
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
// ActivityManager
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
ActivityManager.getService() 获取得到的是IActivityManager的接口,这里涉及到ActivityManagerService(AMS),AMS运行在另外一个进程,继承了IBinder,是一个binder通信的Server端,而IActivityManagerSingleton实现了AMS Binder的client端,这样通过IActivityManagerSingleton就可以跟AMS通信。
2. AMS进程,真正启动Activity
最后ActivityManager.getService().startActivity()通过binder会走到AMS.startActivity();
// AMS
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
// AMS
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,
boolean validateIncomingUser) {
// userId是调用者,检查权限
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho