我们知道当调用context.startActivity()
的时候实际上调用的是contextImpl.startActivity()
,所以本篇从contextImpl.startActivity()
开始,一步步说明一个Activity是如何启动的。由于源码调用过程过于复杂,这里将适当略去一些细节,本篇目的在于在查看源码过程中做辅助作用,这里推荐使用https://cs.android.com/,其次也可以使用更加完整的https://android.googlesource.com来查看源码,不过查找和跳转就没有前者方便了。其次,如果在不知道调用链路的时候,可以在目标处抛出异常,可以利用异常可以打印堆栈的原理,来查看我们的调用链路,这对查看源码十分有帮助。
contextImpl.startActivity()
内容如下:
@Override
public void startActivity(Intent intent, Bundle options) {
....
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
这里mMainThread
是\frameworks\base\core\java\android\app\ActivityThread.java
,getInstrumentation()
得到的是\frameworks\base\core\java\android\app\Instrumentation.java
其对应函数如下:
@UnsupportedAppUsage
public ActivityResult execStartActivity(
....
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//这里调用了ATMS启动Activity,而不是我们熟知的AMS,ATMS是android 10新加入的用于管理Activity的辅助类,
//其Server Name为Context.ACTIVITY_TASK_SERVICE
int result = ActivityTaskManager.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;
}
我们直接到\frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
查看对应的函数,这个函数最终会调用同文件中的startActivityAsUser()
函数,内容如下:
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("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
getActivityStartController()
返回的是\frameworks\base\services\core\java\com\android\server\wm\ActivityStartController.java
,其obtainStarter()
方法如下:
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
这里我们不用关心函数内容,直接看他返回了\frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java
,而上面除了对ActivityStarter
设置一些参数,就是调用了其execute()
函数,所以我们直接看ActivityStarter
的execute()
函数:
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.realCallingPid, mRequest.realCallingUid,
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, mRequest.allowBackgroundActivityStart);
} 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, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
这里两个函数差不多,我们直接追踪startActivity
即可,因为无关代码比较多,读者可以自行追踪,这里直接给出调用链,以供参考:
\frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java中:
startActivity
=> 几个startActivity
同名函数 => startActivityUnchecked
=> mTargetStack.startActivityLocked
=>
\frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java中:
=> startActivityLocked
=> ensureActivitiesVisibleLocked
=> makeVisibleAndRestartIfNeeded
=> mStackSupervisor.startSpecificActivityLocked
\frameworks\base\services\core\java\com\android\server\wm\ActivityStackSupervisor.java中:
startSpecificActivityLocked
startSpecificActivityLocked
内容如下:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
//相应的Activity进程是否启动?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
//如果启动了
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, 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.
knownToBeDead = true;
}
// Suppress transition until the new activity becomes ready, otherwise the keyguard can
// appear for a short amount of time before the new process with the new activity had the
// ability to set its showWhenLocked flags.
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
//如果没有启动
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
可以看到这里对相应的Activity进程是否启动做了一次判断,如果启动了则调用realStartActivityLocked
,没有启动也最终会调用这个函数,所以我们看没有启动的情况,PooledLambda.obtainMessage()
这里不细看了,其作用是在handler中运行某个方法,从参数可以得知,应该是mService.mAmInternal
的ActivityManagerInternal::startProcess
方法,那么这是什么东西呢?读者感兴趣可以自行推断,这里直接给出结果,它就是ActivityManagerService.LocalService#startProcess()
:
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
这里又一次调用了:
startProcessLocked
=> mProcessList.startProcessLocked
\frameworks\base\services\core\java\com\android\server\am\ProcessList.java中
startProcessLocked
=> 几个startProcessLocked
同名函数 => startProcess
:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkSlow(startTime, "startProcess: asking zygote to start proc");
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
//调用Zygote创建新的进程
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*useUsapPool=*/ false,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
这里执行的是appZygote.getProcess().start
,appZygote.getProcess()
返回的是ChildZygoteProcess
,而ChildZygoteProcess
继承了ZygoteProcess
,start
方法也是调用的ZygoteProcess
的start
方法,start
调用了startViaZygote
方法:
private Process.ProcessStartResult startViaZygote(....) throws ZygoteStartFailedEx {
....
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useUsapPool,
argsForZygote);
}
}
这里首先来看openZygoteSocketIfNeeded(abi)
:
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote();
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
可以看到该函数调用了attemptConnectionToPrimaryZygote
和attemptConnectionToSecondaryZygote()
这其实和Zygote()运行的位数有关,32或者64位,他们都调用了ZygoteState.connect
,只是传入的参数不同,我们选择看attemptConnectionToPrimaryZygote
:
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
}
}
然后看ZygoteState.connect
:
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
@Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
DataInputStream zygoteInputStream;
BufferedWriter zygoteOutputWriter;
final LocalSocket zygoteSessionSocket = new LocalSocket();
if (zygoteSocketAddress == null) {
throw new IllegalArgumentException("zygoteSocketAddress can't be null");
}
try {
zygoteSessionSocket.connect(zygoteSocketAddress);
zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
zygoteOutputWriter =
new BufferedWriter(
new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
} catch (IOException ex) {
try {
zygoteSessionSocket.close();
} catch (IOException ignore) { }
throw ex;
}
return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
getAbiList(zygoteOutputWriter, zygoteInputStream));
}
这段代码比较好理解,就是创建一个LocalSocket
和Zygote
建立连接,并获取输入输出流设置到ZygoteState
中,待会儿我们们会用到,至此openZygoteSocketIfNeeded(abi)
调用完成,回到上面的startViaZygote
,代码继续调用了:
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
....
if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
// If there was an IOException using the USAP pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
+ ex.getMessage());
}
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
这段代码意思是,如果使用UASP,就调用attemptUsapSendArgsAndGetResult
,否则调用attemptUsapSendArgsAndGetResult
,Android Q(10)开始,Google引入了一种新的机制:USAP(Unspecialized App Process),详细内容请看:Android Framework | 一种新型的应用启动机制:USAP,也可以看我的另一篇文章Android UASP进程的启动,该篇对UASP进程的启动进行了详细说明,同时也解释了调用attemptUsapSendArgsAndGetResult
的情况,这里我们还是看attemptUsapSendArgsAndGetResult
,没有使用USAP的情况:
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
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.
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
这里可以看到,我们取出上面写入zygoteState
的输入输出流,向其中写入参数,并获取zygote
传回来的创建的进程pid值,至此ActivityManagerService
中的工作就完成了,接下来需要到zygote
看看是如何创建新的进程的了。
在Android系统启动流程末尾,我们说到Zygote进程会执行zygoteServer.runSelectLoop(abiList)
,接收并处理AMS传过来的消息,比如fork app进程。这里我们直接看runSelectLoop
函数即可:
Runnable runSelectLoop(String abiList) {
while (true) {
....
try {
Os.poll(pollFDs, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
....
....
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
}
}
这里runSelectLoop
会使用epoll
机制,阻塞在Os.poll(pollFDs, -1)
,获取对方连接请求后,执行\frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
的processOneCommand
方法:
Runnable processOneCommand(ZygoteServer zygoteServer) {
....
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 {
if (pid == 0) {
// in child
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);
}
}
这里fork
出进程后在子进程执行了handleChildProc
=> ZygoteInit.ZygoteInit
:
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();
RuntimeInit.commonInit();
//开启线程池
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv);
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
////返回可以执行ActivityThread的main函数的Runable
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
这里findStaticMain
其实就是利用反射机制将ActivityThread的main方法打包成Runnable
,这个Runnable
将会在新的进程中运行起来,ActivityThread的main也就是我们熟知的App进程开始的地方。在下篇,我们将详细了解ActivityThread的main,一直执行到Activity的onCreate的过程。