Activity的启动流程有俩种过程,一种是根Activity的启动过程,即在Launch界面点击一个应用图标启动应用程序,根Activity指的是应用程序启动的第一个Activity;另外一种是普通Activity的启动流程,即咱们平时调用startActivity方法来启动一个Activity。本文讨论第二种,startActivity方法你们都知道是用来启动一个Activity的,那么你们有没有想过它在底层是怎么启动的呢?Activity的生命周期方法是如何被回调的?它启动过程当中涉及到多少个进程?接下来咱们经过撸一篇源码来了解Activity的大概启动流程,而后解答这几个问题。html
本文源码基于Android8.0,本文涉及的源码文件位置以下:
frameworks/base/core/java/android/app/Activity.java
frameworks/base/services/core/java/com/android/server/am/*.java(*表明ActivityManagerService,ActivityStack,ActivityStarter,ActivityStackSupervisor,ActivityStack)
复制代码
startActivity有好几种重载方法,以下:java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
//咱们通常没有传options参数给startActivity,因此options为空,就会走到这个分支
//第二参数requestCode为-1,表示不须要知道Activity启动的结果
startActivityForResult(intent, -1);
}
}
//发现两个参数的startActivityForResult方法最终仍是调用三个参数的startActivityForResult方法,options参数传入null
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
复制代码
能够发现startActivity最终都会调用到startActivityForResult方法。android
这里咱们来到了具备三个参数的startActivityForResult方法,以下:git
//Activity.java
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
//mParent一直为空
if (mParent == null) {
//...
//一、关注这里,调用Instrumentation的execStartActivity方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
//...
//此时requestCode为-1
if (requestCode >= 0) {
mStartedActivity = true;
}
//...
} else {
//...
}
复制代码
在上面的的代码中,会进入mParent==null的这个分支里,mParent是Activity类型,它只会在LocalActivityManger构造中被赋值,在咱们startActivity过程当中一直为空(关于为甚么mParent一直为空,能够查看这篇文章StartActivity路上的mParent)。这里咱们只关注注释1,调用Instrumentation的execStartActivity方法,Instrumentation是一个用来监控应用程序与系统交互的类,咱们还要注意传入execStartActivity方法的两个参数:数组
//ActivityThread.java::ApplicationThread
private class ApplicationThread extends IApplicationThread.Stub {
//...
}
复制代码
IApplicationThread.java类是在编译时由IApplicationThread.aidl经过AIDL工具自动生成的,IApplicationThread的内部会自动生成一个 IApplicationThread.Stub类,它继承自Binder类,而Binder实现了IBinder接口,而且 IApplicationThread.Stub实现了IActivityManager接口。要想进行进程间通讯,ApplicationThread只须要继承IApplicationThread.Stub类并实现相应的方法就能够,这样主线程ActivityThread就能够经过ApplicationThread就能对外提供远程服务。要记住这个ApplicationThread,他在Activity的启动过程当中发挥重要做用。架构
咱们继续看Instrumentation的execStartActivity方法,以下:app
//Instrumentation.java
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
//还记得上面提到的ApplicationThread吗,这里把它转成了IApplicationThread,并在下面做为startActivity方法的参数
IApplicationThread whoThread = (IApplicationThread) contextThread;
//...
try {
//...
//一、关注这里,这里实际调用的是ActivityManagerService的startActivity方法
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//检查启动Activity的结果,没法正确启动一个Activiy时,这个方法抛出异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
复制代码
咱们看注释1,ActivityManager.getService()返回的是ActivityManagerService(下面简称AMS)在应用进程的本地代理,该方法在ActivityManager中,以下:ide
//ActivityManager.java
public static IActivityManager getService() {
//IActivityManagerSingleton是Singleton类型,Singleton是一个单例的封装类
//第一次调用它的get方法时它会经过create方法来初始化AMS这个Binder对象,在后续调用中返回以前建立的对象
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//ServiceManager是服务大管家,这里经过getService获取到了IBinder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//这经过asInterface方法把IBinder类型的AMS引用转换成AMS在应用进程的本地代理
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
复制代码
上面出现的IActivityManager.java类的意义相似于前面提到的ApplicationThread.java。要想进行进程间通讯,AMS只须要继承IActivityManager.Stub类并实现相应的方法就能够,这样AMS就能对外提供远程服务,以下:工具
//ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub{
//...
}
复制代码
因此继续回到Instrumentation的execStartActivity方法中,ActivityManager.getService()返回的是AMS的本地代理,注意AMS是在系统进程SystemServer中,因此注释1这里经过Binder的IPC,调用的实际上是AMS的startActivity方法。ui
整个过程的时序图以下:
在这里开始,Activity的启动过程从应用进程转移到AMS中去。
AMS的startActivity方法以下:
//AMS.java
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());
}
复制代码
简单的return了startActivityAsUser方法,该方法在最后多了个 UserHandle.getCallingUserId()参数,AMS根据这个肯定调用者权限。咱们再来看看其余参数:
下面继续看AMS的startActivityAsUser方法。
startActivityAsUser方法以下:
//AMS.java
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) {
//...
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
复制代码
省略了两个判断,一、判断调用者进程是否被隔离,二、判断调用者是否有权限,这些都不是重点。下面继续简单的return了mActivityStarter.startActivityMayWait方法,mActivityStarter是ActivityStarter类型,它是AMS中加载Activity的控制类,会收集全部的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联。传入startActivityMayWait方法的参数又多了几个,看一下几个:
下面看ActivityStarter中的startActivityMayWait方法。
来看看这个方法的源码,以下:
//ActivityStarter.java
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask, String reason) {
//...
//把上面传进来的intent再构造一个新的Intent对象,这样即使intent被修改也不受影响
intent = new Intent(intent);
//...
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
if(rInfo == null){
//...
}
//解析这个intent,收集intent指向的Activity信息
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
//...
final ActivityRecord[] outRecord = new ActivityRecord[1];
//一、主要关注这里,调用了自己的startActivityLocked方法
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask, reason);
//...
return res;
}
复制代码
ActivityInfo里面收集了要启动的Activity信息(关于ResolveInfo与ActivityInfo能够看这篇如何获取Android应用与系统信息),主要仍是关注注释1,这里又调用了ActivityStarter中的startActivityLocked方法。传入startActivityLocked方法的参数又多了几个(callingPid等)。关于pid于与uid的介绍能够看这篇文章Android手机中UID、PID做用及区别。
下面来看一下startActivityLocked方法。
该方法的相关源码以下:
//ActivityStarter.java
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask, String reason) {
//这里对上面传进来值为"startActivityAsUser"理由参数判空
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
//一、主要关注这里,调用了自己的startActivity方法
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
if (outActivity != null) {
outActivity[0] = mLastStartActivityRecord[0];
}
return mLastStartActivityResult;
}
复制代码
这里主要关注注释1,调用了ActivityStarter中的startActivity方法,该方法多了一个参数,最后一个mLastStartActivityRecord,mLastStartActivityRecord是一个ActivityRecord数组类型,ActivityRecord是用来保存一个Activity的全部信息的类。
下面来看ActivityStarter中的startActivity方法。
//ActivityStarter.java
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
//...
//获取调用者所在进程记录的对象,caller就是上面一直强调的表明调用者进程的ApplicationThread对象
ProcessRecord callerApp = null;
if (caller != null) {
//这里调用AMS的getRecordForAppLocked方法得到表明调用者进程的callerApp
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
//获取调用者进程的pid与uid并赋值
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
err = ActivityManager.START_PERMISSION_DENIED;
}
}
//下面startActivity方法的参数之一,表明调用者Activity的信息
ActivityRecord sourceRecord = null;
if (resultTo != null) {
sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
//...
}
//...
//建立即将要启动的Activity的信息描述类ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);
//outActivity是ActivityRecord[]类型,从上面传进来,这里把ActivityRecord赋值给了它,下面会做为参数传进startActivity方法中
if (outActivity != null) {
outActivity[0] = r;
}
//...
//一、关注这里,调用了自己的另外一个startActivity方法
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
复制代码
上面的startActivity代码很是长,省略了不少,上面讲的调用者进程,在这里等价于应用程序进程,ProcessRecord是用来描述一个应用进程的信息,ActivityRecord上面也讲过了,就是用来记录一个要启动的Activity的全部信息,在注释1处的调用了ActivityStarter的startActivity方法,这个方法参数少了不少,大多数有关要启动的Activity的信息都被封装进了ActivityRecord类中,做为参数r传了进去。
下面来看ActivityStarter的startActivity方法。
该方法代码以下:
//ActivityStarter.java
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
//一、主要关注这里,调用自己的startActivityUnchecked方法
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
//...
mService.mWindowManager.continueSurfaceLayout();
}
//...
return result;
}
复制代码
这里主要调用了ActivityStarter的startActivityUnchecked方法。
该方法代码以下:
//ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
//把上面传进来的参数除了outActivity都传进去了,主要是把这些参数赋值给ActivityStarter的成员变量,如mDoResume = doResume, mStartActivity = r
//mStartActivity就是即将要启动的Activity的信息
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
//计算出启动Activity的模式,并赋值给mLaunchFlags
computeLaunchingTaskFlags();
//...
//设置启动模式
mIntent.setFlags(mLaunchFlags);
//...
boolean newTask = false;
//一、下面会进行判断,到底需不须要建立一个新的Activity任务栈
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
//1.1走这里就会在setTaskFromReuseOrCreateNewTask方法内部建立一个新的Activity任务栈
newTask = true;
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
//1.2走这里就会在setTaskFromSourceRecord方法内部得到调用者Activity的的任务栈赋值给mTargetStack
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
//1.3走这里就会在setTaskFromInTask方法内部直接把mInTask赋值给mTargetStack,前面已经说过mInTask等于null
result = setTaskFromInTask();
} else {
//1.四、就是前面的条件都不知足了,可是这种状况不多发生
setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}
//...
//mDoResume等于上面传进来的doResume,为true
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
//走这里不会显示Activity,由于Activity尚未获取焦点或者Activity的栈溢出
//...
} else {
//正常的话会走到这里
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
//二、主要关注这里调用mSupervisor的resumeFocusedStackTopActivityLocked方法
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
//...
}
return START_SUCCESS;
}
复制代码
上面的startActivityUnchecked方法也是很长,这个方法主要处理Activity栈管理相关的逻辑,若是对于这方面信息不熟悉的话能够查看这两篇文章Android任务和返回栈彻底解析、ActivityTask和Activity栈管理。一个或多个ActivityRecord会组成一个TaskRecord,TaskRecord用来记录Activity的栈,而ActivityStack包含了一个或多个TaskRecord。上面代码的mTargetStack就是ActivityStack类型,咱们先来看注释1,注释1会根据mLaunchFlags等条件到底需不须要建立一个新的Activity任务栈,而本文所讨论的条件限定在从一个应用程序调用Activity的startActivity去启动另一个Activity的情景,并且默认Activity的启动模式是standard,并不会建立一个新的任务栈,因此就会走到1.2的条件分支,而后咱们再来看注释2,这里会调用mSupervisor.resumeFocusedStackTopActivityLocked方法,mSupervisor是ActivityStackSupervisor类型,ActivityStackSupervisor主要用来管理ActivityStack。启动Activity的过程从ActivityStack来到了ActivityStackSupervisor。
下面咱们来看ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法。
该方法源码以下:
//ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//...
//获取要启动的Activity所在栈的栈顶的ActivityRecord
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
//一、r是否null或是否为RESUMED状态
if (r == null || r.state != RESUMED) {
//二、关注这里,调用ActivityStack的resumeTopActivityUncheckedLocked方法
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
复制代码
首先这里会获取要启动的Activity所在栈的栈顶的ActivityRecord赋值给r,由于要启动的Activity的尚未启动,因此此时栈顶就是调用者Activity,调用者Activity启动Activity,确定会从RESUME状态转到其余状态如STPO,因此注释1知足r.state != RESUMED的条件,此时就是走带注释2,注释2调用了mFocusedStack的resumeTopActivityUncheckedLocked方法,mFocusedStack就是ActivityStack类型。启动Activity的过程从ActivityStackSupervisor又回到到了ActivityStack。
下面咱们来看ActivityStack的resumeTopActivityUncheckedLocked方法。
该方法的源码以下:
//ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//...
boolean result = false;
try {
//一、关注这里,这里调用了自己的resumeTopActivityInnerLocked方法
result = resumeTopActivityInnerLocked(prev, options);
} finally {
//...
}
//...
return result;
}
复制代码
咱们来看注释1,简单的调用了resumeTopActivityInnerLocked方法。
该方法源码以下:
//ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//...
//得到将要启动的Activity的信息
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */)
//...
if (next.app != null && next.app.thread != null) {
//...
}else{
//...
//一、关注这里,调用了ActivityStackSupervisor的startSpecificActivityLocked方法
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
复制代码
topRunningActivityLocked方法得到将要启动的Activity的信息next,由于此时要启动的Activity还不属于任何进程,故它的ProcessRecord为空成立,就会走到else分支,因此注释1这里调用了ActivityStackSupervisor的startSpecificActivityLocked方法,又回到了ActivityStackSupervisor中。
下面来看ActivityStackSupervisor的startSpecificActivityLocked方法。
该方法源码以下:
//ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//获取要启动的Activity的所在应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
//要启动的Activity的所在应用程序进程存在
if (app != null && app.thread != null) {
try {
//...
//一、关注这里,调用了自己的realStartActivityLocked方法
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
//...
}
}
//...
}
复制代码
这里首先会获取要启动的Activity所在的应用进程app,当app进程已经运行时,就会调用注释1处的realStartActivityLocked方法,注意这里多了一个参数,把表明应用进程的app传了进去。
下面来看ActivityStackSupervisor的realStartActivityLocked方法。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
//...
//一、把应用所在进程信息赋值给要启动的Activity的ActivityRecord
r.app = app;
//...
try{
//...
//二、关注这里,app是ProcessRecord类型,app.thread是IApplicationThread类型
//app.thread是应用进程的ApplicationThread在AMS的本地代理,前面已经讲过
//因此这里实际调用的是ApplicationThread的scheduleLaunchActivity方法
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
//...
}catch (RemoteException e) {
//...
}
//...
return true;
}
复制代码
正如这方法名所示,realStartActivity,兜兜转转,这里就是真正启动Activity的地方,注释1处app指的是传入的要启动的Activity的所在的应用程序进程,是从前面传过来的,这里把它赋值给了要启动的Activity的ActivityRecord的app字段去,这样就能够说要启动的Activity属于应用进程,咱们再来看注释2这里,app.thread就是咱们上面一直强调的ApplicationThread,因此这里经过Binder的IPC其实调用的是ApplicationThread中的scheduleLaunchActivity方法。
整个过程的时序图以下:
当前的代码逻辑执行在AMS所在进程,从这里开始Activity的启动流程最终又回到了应用进程所在的ApplicationThread中。
原本一篇文章写完Activity的启动,写到这里才发现,篇幅太长,因此Activity在应用进程中的启动过程就放到下一篇文章。本文简单的介绍了应用进程请求AMS启动Activity过程和Activity在AMS中的启动过程,如今让咱们来回答一下开头给出的几个问题:
从应用调用一个startActivity方法开始,应用进程开始请求AMS启动Activity,而后在AMS中Activity完成它的一系列准备,最后再回到应用进程中开始回调Activity的生命周期,本文回答了一半这个问题,即本文讲解了应用进程开始请求AMS启动Activity,而后在AMS中完成它的一系列准备的过程,这个过程用时序图表示以下:
本文并无解答这个问题,这个问题要到下一篇文章才能有答案。
答案是2个,前言已经讲过本文讨论的是普通Activity的启动流程,即咱们平时调用startActivity方法来启动一个Activity,因此本文这个过程涉及的进程能够能够用下面这个图表示:
图中AppProcess表明应用所在进程,systemServer表明AMS所在进程,两个进程之间经过Binder进行通讯,实现了XX.Stub的类就能够进行Binder通讯,如本文的ApplicationThread和AMS都实现了各自的Stub类,因此应用进程startActivity时请求AMS启动Activity,AMS准备好后,再发送scheduleLaunchActivity请求告诉应用能够开始启动Activity了。
那么若是是前言所讲的第一种启动Activity的过程,即在Launch界面点击一个应用图标启动应用程序,那么会涉及多少个进程?答案是4个,如图:
能够看到会涉及Launcher进程、SystemServer进程、App进程、Zygote进程。关于这些进程的简单信息能够看这篇从进程的角度看Android的系统架构
阅读源码真的是一个漫长的过程,又时候看别人写的那么简单,可是当本身去写,才发现要考虑的东西不少,因此这是一个日积月累的过程,因此阅读源码的时候,最好跟着前人的文章阅读,这样理解的更快。
参考文章:
《Android开发艺术探索》