注:下列源码均基于9.0,可经过下列方式下载本文相关源码到本地:html
- git clone aosp.tuna.tsinghua.edu.cn/platform/pa…
- git clone aosp.tuna.tsinghua.edu.cn/platform/fr…
参考博客:如何下载和阅读Android源码java
本篇文章将根据源码解剖Android的Activity的启动流程,需注意的是下列的分析均基于Android9.0, 9.0版本相较于以前几个版本作了许多改动和重构,可是总体的流程是变化不大。根据启动Activity时机的不一样,可分为根Activity的启动流程和普通Activity启动流程,根Activity启动流程又能够称为应用程序启动流程,即在桌面上点击一个应用图标到进入到应用第一个Activity的流程。而普通Activity的启动流程就是在一个应用里开启另一个Activity的流程。因为两种启动流程是有重叠的,而根Activity的启动流程更加复杂,因此接下来咱们重点分析根Activity的启动流程,而普通Activity的启动流程在涉及的地方会稍微提一下。因为考虑到篇幅较长,这里将分为两篇来介绍。android
这篇将分析启动流程中的应用进程的建立:git
上面咱们提到根Activity的启动流程其实就是桌面上点击一个应用图标进入到应用的第一个Activity的流程,其实桌面也能够当作一个程序,即Launcher。当系统开机后,Launcher也随之被启动,而后将已经安装的应用程序图标显示到桌面上,因此当咱们点击一个应用图标其实就是至关于点击活动中的一个button,其相应事件就是Launcher进程请求AMS来启动该应用程序。web
请求的入口就是Launcher的startActivitySafe方法,以下:session
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java并发
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
...
// 根Activity会在新的任务栈中启动
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
...
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// 调用startActivity
startActivity(intent, optsBundle);
} else {
LauncherAppsCompat.getInstance(this).startActivityForProfile(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
...
return true;
} catch (ActivityNotFoundException|SecurityException e) {
...
}
return false;
}
复制代码
能够发现该方法为根Activity设置了flag,即根Activity会在新的任务栈中启动。而后会调用咱们熟悉的startActivity方法,而在Launcher并无这个方法,因此咱们天然想到了应该是父类的方法,而后让咱们来看看Launcher继承了哪些类?app
public class Launcher extends BaseDraggingActivity implements LauncherExterns, LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate{
}
public abstract class BaseDraggingActivity extends BaseActivity implements WallpaperColorInfo.OnChangeListener {
}
public abstract class BaseActivity extends Activity implements UserEventDelegate{
}
复制代码
其实一直追踪下去,你就会发现其实Launcher调用的startActivity其实就是Activity中的startActivity。从这里也能够证实Launcher其实也是个Activity。因此在Launcher启动一个app,和咱们平时在startActivity基本是同样的(基本同样,不表明彻底同样,经过后文分析你就会明白!),因而咱们来看看咱们熟悉的Activity中的startActivity的源码是如何的:socket
源码:frameworks/base/core/java/android/app/Activity.javaide
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
//第二个参数为-1表示Launcher不须要知道根Activity的启动结果
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
//mParent表示当前Activity的父类,当根活动还没建立则mParent==null
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
...
}
复制代码
从上面代码能够发现startActivity的最终实现是startActivityForResult,startActivity()第二个参数为-1表示Launcher不须要知道根Activity的启动结果,而后在startActivityForResult中因为此时根Activity尚未建立,故mParent=null,因此咱们只须要关注mParent=null的状况。在这种状况中会调用Instrumentation的execStartActivity。这时候也许你就会问这个Instrumentation是什么?为何要交给她弄呢?其实Instrumentation这个类很重要,重要体如今对Activity生命周期的调用根本离不开她。每一个Activity都持有Instrumentation对象的一个引用,可是整个进程只会存在一个Instrumentation对象。回归正题,让咱们瞧瞧Instrumentation的execStartActivity这个方法。
frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
...
try {
...
//获取AMS的代理对象
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
复制代码
在这个方法会调用ActivityManager的getService方法来获得AMS的代理对象,而后调用这个代理对象的
startActivity方法,那么这个代理对象是谁呢?让咱们一探究竟
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//获得activity的service引用,即IBinder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//转换成IActivityManager对象
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
复制代码
能够发如今Singleton中的create方法中因为b是AMS引用做为服务端处于SystemServer进程中,与当前Launcher进程做为客户端与服务端不在同一个进程,因此am返回的是IActivityManager.Stub的代理对象,此时若是要实现客户端与服务端进程间的通讯,只须要在AMS继承了IActivityManager.Stub类并实现了相应的方法,而经过下面的代码能够发现AMS恰好是继承了IActivityManager.Stub类的,这样Launcher进程做为客户端就拥有了服务端AMS的代理对象,而后就能够调用AMS的方法来实现具体功能了,就这样Launcher的工做就交给AMS实现了。
public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
}
复制代码
经过上面的分析,咱们已经知道如今任务已经交给了AMS,入口是AMS的startActivity。
首先来看看在AMS中的startActivity方法:
源码:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
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());
}
@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) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
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) {
//判断调用者的进程是否隔离
enforceNotIsolatedCaller("startActivity");
//检查调用者权限
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
复制代码
startActivity方法通过多个方法调用会去执行startActivityAsUser方法,在startActivityAsUser方法最后会返回mActivityStartController的一长串链式调用方法,若是AlertDialog的话,应该不难看出这链式方法确定都是返回一个类型的对象的,咱们只须要看看obtainStarter的返回类型就能够知道这个对象是什么类型了。
frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
复制代码
能够发现这个obtainStarter返回的是ActivityStarter类型的,因此链式方法就是对ActivityStarter对象设置了要启动的活动的相关信息,最后再调用ActivityStarter对象execute方法。因此咱们下一步所须要看的就是这个execute方法。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent);
}
} finally {
onExecutionComplete();
}
}
复制代码
由于在startActivityAsUser的链式方法中咱们调用了setMayWait这个方法,因此这里的mRequest.mayWait为true,故会继续调用startActivityMayWait方法。
ActivityStarter#startActivityMayWait
private 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, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent) {
.....
//根据intent在系统中找到合适的应用的activity,若是有多个activity可选择,
//则会弹出ResolverActivity让用户选择合适的应用。
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
....
}
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, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup) {
...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup);
...
return getExternalResult(mLastStartActivityResult);
}
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, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
...
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
...
postStartActivityProcessing(r, result, mTargetStack);
return result;
}
复制代码
startActivityMayWait方法通过调用屡次的startActivity方法后会调用到startActivityUnchecked这个方法,那这个方法是干啥的呢?这个方法会根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图从新启动它。好比咱们在一开始将活动设置了FLAG_ACTIVITY_NEW_TASK后将建立一个任务栈,其它的就自行看代码。
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
...
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
//建立新的TaskRecord
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
setTaskToCurrentTopOrCreateNewTask();
}
...
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
...
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
...
}
复制代码
而后不管以何种模式启动最终都会调用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked方法。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
....
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
....
}
复制代码
因而又调用了ActivityStack的resumeTopActivityUncheckedLocked
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
}
...
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
复制代码
emmmm.....,看到这估计都懵逼了,几个类跳来跳去也不知道干了些什么,不慌,让咱们坚持看下ActivityStackSupervisor.startSpecificActivityLocked,由于这个方法很重要。这个方法将是普通Activity和根Activity启动流程的分岔路口。
ActivityStackSupervisor#startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//获取即将要启动的Activity的所在的应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
//若是应用进程已经存在
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
//应用进程还未建立,则经过AMS调用startProcessLocked向Zygote进程发送请求
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
复制代码
阅读上面的代码咱们能够知道在方法中首先获取到了即将要启动的Activity所在的应用进程,假如是普通的Activity的启动流程的活,这个进程确定是存在的,因此将执行realStartActivityLocked的方法。可是咱们如今讨论的是根Activity的启动流程,因为应用都还未启动,意味着根Activity所在的应用进程还未建立,而mService其实就是AMS,因此这里将调用AMS的startProcessLocked。因而咱们又回到了最初的起点AMS。
ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
...
final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
...
}
@GuardedBy("this")
private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride) {
return startProcessLocked(app, hostingType, hostingNameStr,
false /* disableHiddenApiChecks */, abiOverride);
}
private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
...
int uid = app.uid; //建立应用进程的用户ID
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
checkTime(startTime, "startProcess: getting gids from package manager");
final IPackageManager pm = AppGlobals.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName,
MATCH_DEBUG_TRIAGED_MISSING, app.userId);
StorageManagerInternal storageManagerInternal = LocalServices.getService(
StorageManagerInternal.class);
mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
app.info.packageName);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
/* * 对用户组进行建立和赋值 */
if (ArrayUtils.isEmpty(permGids)) {
gids = new int[3];
} else {
gids = new int[permGids.length + 3];
System.arraycopy(permGids, 0, gids, 3, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
// Replace any invalid GIDs
if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
}
...
//这个参数后文会提到
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
}
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) {
....
//重点关注
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
requiredAbi, instructionSet, invokeWith, app.startTime);
...
}
private ProcessStartResult startProcess(String hostingType, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) {
....
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
//经过Process.start方法来为应用建立进程
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkTime(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
复制代码
是否是又惊呆了,好吧,我也惊呆了!反正就是经过调用多个startProcessLocked方法后最终将调用startProcess方法,不过须要重点看一下上面的第四个startProcessLocked,在该方法中有个entryPoint参数为 "android.app.ActivityThread",这个参数将在后文讲到建立应用进程后启动ActivityThread会用到。而后在startProcess方法里将调用Process.start来发送应用建立进程的请求。这样AMS就将发送请求的事交给了Process
frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith,
/*useBlastulaPool=*/ true, zygoteArgs);
}
public final Process.ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, boolean useBlastulaPool, String[] zygoteArgs) {
try {
//重点关注
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith,
/*startChildZygote=*/false,
useBlastulaPool, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
复制代码
从上面能够发现,Process中的start方法的实现是startViaZygote方法,因此咱们重点观察下这个方法。
private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, boolean useBlastulaPool, String[] extraArgs) throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
//建立字符串列表argsForZygote,并将启动应用进程的启动参数保存在这个列表中
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
...
synchronized(mLock) {
//重点关注
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useBlastulaPool,
argsForZygote);
}
}
复制代码
在startViaZygote中会建立字符串列表argsForZygote来保存将要建立的应用进程的启动参数,而后最后会调用zygoteSendArgsAndGetResult方法,而在这个方法中第一个参数会调用openZygoteSocketIfNeeded方法,第三个参数就是启动参数列表。因此咱们先看看openZygoteSocketIfNeeded这个方法的实现。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
//64位进程中的
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
//调用ZygoteState的connect函数与mZygoteSocketAddress创建链接,
//这里mZygoteSocketAddress的值为“zygote”
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mBlastulaPoolSocketAddress);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) {
//Socket进行链接成功并匹配abi后会返回ZygoteState类型对象
return primaryZygoteState;
}
// 32位Zygote进程中
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState =
ZygoteState.connect(mZygoteSecondarySocketAddress,
mBlastulaPoolSecondarySocketAddress);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
复制代码
openZygoteSocketIfNeeded这个方法从方法名就能够推测出这个方法的做用,大概就是与Zygote创建Socket链接。而从代码中也证明了这一点,在代码中会根据Zygote进程的位数来创建相应的Socket链接,而后返回ZygoteState类型的对象。既然与Zygote创建好Socket链接后,接下来固然是发送请求啦!因此让咱们来看看zygoteSendArgsAndGetResult这个方法中是如何发送请求的!
//将传入的应用进程的启动参数argsForZygote写入到ZygoteState
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, boolean useBlastulaPool, ArrayList<String> args) throws ZygoteStartFailedEx {
String msgStr = Integer.toString(args.size()) + "\n"
+ String.join("\n", args) + "\n";
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
// TODO (chriswailes): Move branch body into separate function.
if (useBlastulaPool && Zygote.BLASTULA_POOL_ENABLED && isValidBlastulaCommand(args)) {
LocalSocket blastulaSessionSocket = null;
try {
blastulaSessionSocket = zygoteState.getBlastulaSessionSocket();
final BufferedWriter blastulaWriter =
new BufferedWriter(
new OutputStreamWriter(blastulaSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
final DataInputStream blastulaReader =
new DataInputStream(blastulaSessionSocket.getInputStream());
blastulaWriter.write(msgStr);
blastulaWriter.flush();
result.pid = blastulaReader.readInt();
// Blastulas can't be used to spawn processes that need wrappers.
result.usingWrapper = false;
if (result.pid < 0) {
throw new ZygoteStartFailedEx("Blastula specialization failed");
}
return result;
} catch (IOException ex) {
// If there was an IOException using the blastula pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with blastula pool - "
+ ex.toString());
} finally {
try {
blastulaSessionSocket.close();
} catch (IOException ex) {
Log.e(LOG_TAG, "Failed to close blastula session socket: " + ex.getMessage());
}
}
}
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr);
zygoteWriter.flush();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
}
复制代码
由于在openZygoteSocketIfNeeded中咱们已经与Zygote进程创建了Socket链接,因此在这个方法中将传入的应用进程的启动参数argsForZygote写入到ZygoteState。这样AMS就完成了向Zygote进程发送建立应用进程的请求的任务。
从上面咱们知道,AMS已经与Zygote进程创建Socket链接并发送了建立应用进程的请求,那么Zygote进程是在哪里收到请求,收到请求后又是怎么处理的呢?这里能够停下来先看看刘望舒的Android系统启动流程(二)解析Zygote进程启动过程,写的很不错。不过因为咱们分析的源码基于8.0,可能会稍微不一样,但整体上来大体流程是同样的。经过阅读后咱们知道Zygote进程是在ZygoteInit的main方法中接受请求的。因此如今的入口就是ZygoteInit的main方法。
从时序图与上面的分析咱们知道如今Zygote进程接受请求是在main方法,就让咱们来看看这个main方法
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
@UnsupportedAppUsage
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
Runnable caller;
try {
...
//建立名为zygote的Socket
zygoteServer.createZygoteSocket(socketName);
....
//因为在init.rc中设置了start-system-server参数,所以
//这里将启动SystemServer,可见SystemServer由Zygote建立的第一个进程
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
caller = Zygote.initBlastulaPool();
if (caller == null) {
Log.i(TAG, "Accepting command socket connections");
//等待AMS的请求
caller = zygoteServer.runSelectLoop(abiList);
}
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
复制代码
经过main方法,咱们能够知道在这个main方法首先要建立一个Server端的Socket,这个name为”zygote”的Socket用来等待ActivityManagerService来请求Zygote来建立新的应用程序进程,在上面AMS请求的分析中咱们也知道客户端将根据这个name来与Zygote的Socket创建链接。接下去会启动SystemServer进程,这个进程会启动各类系统服务,好比与Activity启动息息相关的AMS。最后会调用ZygoteServer.runSelectLoop(abiList)来使建立的Socket进入无限循环,等待AMS请求。让咱们来看看这个runSelectLoop
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
peers.add(null);
while (true) {
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
//监听Socket链接,充当服务端Socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < blastulaPoolEventFDIndex) {
try {
//不断处理客户端的AMS的请求,而后交给processOneCommand
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
}
....
}
}
}
}
复制代码
能够发现这个方法是死循环表示不停的监听着Socket链接。acceptCommandPeer方法就是监听是否收到了请求,若是收到了请求就交给processOneCommand来实现
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
ZygoteArguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
//获取应用程序进程的启动参数
args = Zygote.readArgumentList(mSocketReader);
// TODO (chriswailes): Remove this and add an assert.
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
....
parsedArgs = new ZygoteArguments(args);
....
//fork当前进程建立一个子进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
//pid为0则表明这个进程为子进程,即新建立的应用程序进程
if (pid == 0) {
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
复制代码
在这个方法中将对请求进行处理,首先获取到将要启动的应用进程的启动参数,而后调用forkAndSpecialize来建立应用进程。
frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir, int targetSdkVersion) {
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {
Zygote.disableExecuteOnly(targetSdkVersion);
Trace.setTracingEnabled(true, runtimeFlags);
// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
ZygoteHooks.postForkCommon();
return pid;
}
复制代码
在forkAndSpecialize中,最终将建立应用进程的任务交给nativeForkAndSpecialize,而这个方法能够看出来应该是本地方法,因此具体如何建立的咱们就不深究了,在这里咱们这须要知道nativeForkAndSpecialize最终是经过fork当前线程来建立一个子线程,而fork后会有返回值给pid:
因而到这里子线程也就是应用进程就被孵化出来了。你觉得这样就结束了?其实还早呢!别忘了咱们的最终使命是根Activity的启动,而如今只是有了根Activity所须要的应用进程,革命还没有成功,仍须要努力!
从上面咱们知道应用进程已经被建立,那建立后呢?这就须要咱们回头看上面的processOneCommand方法,细心的你确定会发现再孵化出应用进程后,仍是有返回值的。
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
....
//fork当前进程建立一个子进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
//pid为0则表明这个进程为子进程,即新建立的应用程序进程
if (pid == 0) {
....
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
...
}
}
....
}
复制代码
在上面咱们分析了当pid=0的时候,则表明了当前进程已是子进程了,即应用进程。因此下一步将执行handleChildProc方法。
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {
.....
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
....
}
}
复制代码
而handleChildProc最终又会调用ZygoteInit.zygoteInit方法。以下
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
//为当前的VM设置未捕获异常器
RuntimeInit.commonInit();
//Binder驱动初始化,该方法完成后,可经过Binder进行进程通讯
ZygoteInit.nativeZygoteInit();
//主要调用SystemServer的main方法
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
复制代码
在这个方法里会建立当前进程的Binder线程池,便于后续与其它进程通讯,而后调用了RuntimeInit的applicationInit方法,以下:
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
...
final Arguments args = new Arguments(argv);
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
复制代码
这个方法最终会调用findStaticMain方法,不过需注意的是方法的第一个参数args.startClass其实就是咱们上文AMS将请求任务转移给Process中在最后强调的那个参数:android.app.ActivityThread。而后咱们看看findStaticMain的实现
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);//1
} catch (ClassNotFoundException ex) {
....
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });//2
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}
return new MethodAndArgsCaller(m, argv);
}
复制代码
在这个方法中首先在注释1经过反射获取到android.app.ActivityThread类,而后在注释2获取到ActivityThread的main方法,最后经过main方法来构造MethodAndArgsCaller。而这个MethodAndArgsCaller是什么呢?以下:
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
复制代码
追踪下去,MethodAndArgsCaller实际上是RuntimeInit的一个内部类而且继承了Runnable,而后在run方法中会经过反射调用了mMethod方法,此时mMethod是ActivityThread的main方法,即run方法中将会执行ActivityThread的main方法,在这里你可能会有疑问了,那这个run方法何时执行呢?让咱们来看看最开始的ZygoteInit的main方法。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
@UnsupportedAppUsage
public static void main(String argv[]) {
Runnable caller;
try {
....
caller = Zygote.initBlastulaPool();
if (caller == null) {
Log.i(TAG, "Accepting command socket connections");
//等待AMS的请求
caller = zygoteServer.runSelectLoop(abiList);
}
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
复制代码
有没有恍然大悟呢?从分析Zygote进程接受请求并孵化应用进程的一开始,咱们就是分析zygoteServer.runSelectLoop(abiList)这个方法,而分析到最后findStaticMain方法将返回MethodAndArgsCaller对象(继承Runnable),因此这时候在ZygoteInit的main方法caller会等于这个MethodAndArgsCaller对象,显然caller不等于null,故最后会执行caller.run方法,即执行ActivityThread的main方法。因而应用进程成功启动ActivityThread。
分析到这,咱们已经愈来愈接近万里长征的终点了!不过仍是得歇歇,养足精力,才能走到终点。下篇博客Android之9.0Activity启动流程(二)将分析Activity启动流程的剩下部分。即:
参考博客: