我們知道當(dāng)調(diào)用context.startActivity()
的時(shí)候?qū)嶋H上調(diào)用的是contextImpl.startActivity()
闻坚,所以本篇從contextImpl.startActivity()
開始法绵,一步步說明一個(gè)Activity是如何啟動(dòng)的坛善。由于源碼調(diào)用過程過于復(fù)雜歇式,這里將適當(dāng)略去一些細(xì)節(jié),本篇目的在于在查看源碼過程中做輔助作用逻住,這里推薦使用https://cs.android.com/创葡,其次也可以使用更加完整的https://android.googlesource.com來查看源碼,不過查找和跳轉(zhuǎn)就沒有前者方便了唠叛。其次只嚣,如果在不知道調(diào)用鏈路的時(shí)候,可以在目標(biāo)處拋出異常艺沼,可以利用異巢嵛瑁可以打印堆棧的原理,來查看我們的調(diào)用鏈路障般,這對(duì)查看源碼十分有幫助调鲸。
contextImpl.startActivity()
內(nèi)容如下:
@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
其對(duì)應(yīng)函數(shù)如下:
@UnsupportedAppUsage
public ActivityResult execStartActivity(
....
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//這里調(diào)用了ATMS啟動(dòng)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
查看對(duì)應(yīng)的函數(shù)定拟,這個(gè)函數(shù)最終會(huì)調(diào)用同文件中的startActivityAsUser()
函數(shù)于微,內(nèi)容如下:
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);
}
這里我們不用關(guān)心函數(shù)內(nèi)容,直接看他返回了\frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java
,而上面除了對(duì)ActivityStarter
設(shè)置一些參數(shù)角雷,就是調(diào)用了其execute()
函數(shù)祸穷,所以我們直接看ActivityStarter
的execute()
函數(shù):
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();
}
}
這里兩個(gè)函數(shù)差不多,我們直接追蹤startActivity
即可勺三,因?yàn)闊o關(guān)代碼比較多雷滚,讀者可以自行追蹤,這里直接給出調(diào)用鏈吗坚,以供參考:
\frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java中:
startActivity
=> 幾個(gè)startActivity
同名函數(shù) => 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
內(nèi)容如下:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
//相應(yīng)的Activity進(jìn)程是否啟動(dòng)祈远?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
//如果啟動(dòng)了
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.
//如果沒有啟動(dòng)
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);
}
}
可以看到這里對(duì)相應(yīng)的Activity進(jìn)程是否啟動(dòng)做了一次判斷,如果啟動(dòng)了則調(diào)用realStartActivityLocked
商源,沒有啟動(dòng)也最終會(huì)調(diào)用這個(gè)函數(shù)车份,所以我們看沒有啟動(dòng)的情況,PooledLambda.obtainMessage()
這里不細(xì)看了牡彻,其作用是在handler中運(yùn)行某個(gè)方法扫沼,從參數(shù)可以得知庄吼,應(yīng)該是mService.mAmInternal
的ActivityManagerInternal::startProcess
方法缎除,那么這是什么東西呢渐行?讀者感興趣可以自行推斷,這里直接給出結(jié)果,它就是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);
}
}
這里又一次調(diào)用了:
startProcessLocked
=> mProcessList.startProcessLocked
\frameworks\base\services\core\java\com\android\server\am\ProcessList.java中
startProcessLocked
=> 幾個(gè)startProcessLocked
同名函數(shù) => 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);
//調(diào)用Zygote創(chuàng)建新的進(jìn)程
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);
}
}
這里執(zhí)行的是appZygote.getProcess().start
孽文,appZygote.getProcess()
返回的是ChildZygoteProcess
驻襟,而ChildZygoteProcess
繼承了ZygoteProcess
,start
方法也是調(diào)用的ZygoteProcess
的start
方法芋哭,start
調(diào)用了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);
}
可以看到該函數(shù)調(diào)用了attemptConnectionToPrimaryZygote
和attemptConnectionToSecondaryZygote()
這其實(shí)和Zygote()運(yùn)行的位數(shù)有關(guān)沉衣,32或者64位,他們都調(diào)用了ZygoteState.connect
减牺,只是傳入的參數(shù)不同豌习,我們選擇看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));
}
這段代碼比較好理解存谎,就是創(chuàng)建一個(gè)LocalSocket
和Zygote
建立連接,并獲取輸入輸出流設(shè)置到ZygoteState
中肥隆,待會(huì)兒我們們會(huì)用到既荚,至此openZygoteSocketIfNeeded(abi)
調(diào)用完成,回到上面的startViaZygote
栋艳,代碼繼續(xù)調(diào)用了:
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,就調(diào)用attemptUsapSendArgsAndGetResult
吸占,否則調(diào)用attemptUsapSendArgsAndGetResult
晴叨,Android Q(10)開始,Google引入了一種新的機(jī)制:USAP(Unspecialized App Process)矾屯,詳細(xì)內(nèi)容請(qǐng)看:Android Framework | 一種新型的應(yīng)用啟動(dòng)機(jī)制:USAP兼蕊,也可以看我的另一篇文章Android UASP進(jìn)程的啟動(dòng),該篇對(duì)UASP進(jìn)程的啟動(dòng)進(jìn)行了詳細(xì)說明件蚕,同時(shí)也解釋了調(diào)用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);
}
}
這里可以看到骤坐,我們?nèi)〕錾厦鎸懭?code>zygoteState的輸入輸出流绪杏,向其中寫入?yún)?shù),并獲取zygote
傳回來的創(chuàng)建的進(jìn)程pid值纽绍,至此ActivityManagerService
中的工作就完成了,接下來需要到zygote
看看是如何創(chuàng)建新的進(jìn)程的了势似。
在Android系統(tǒng)啟動(dòng)流程末尾拌夏,我們說到Zygote進(jìn)程會(huì)執(zhí)行zygoteServer.runSelectLoop(abiList)
,接收并處理AMS傳過來的消息履因,比如fork app進(jìn)程障簿。這里我們直接看runSelectLoop
函數(shù)即可:
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
會(huì)使用epoll
機(jī)制,阻塞在Os.poll(pollFDs, -1)
栅迄,獲取對(duì)方連接請(qǐng)求后站故,執(zhí)行\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
出進(jìn)程后在子進(jìn)程執(zhí)行了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);
////返回可以執(zhí)行ActivityThread的main函數(shù)的Runable
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
這里findStaticMain
其實(shí)就是利用反射機(jī)制將ActivityThread的main方法打包成Runnable
,這個(gè)Runnable
將會(huì)在新的進(jìn)程中運(yùn)行起來毅舆,ActivityThread的main也就是我們熟知的App進(jìn)程開始的地方西篓。在下篇,我們將詳細(xì)了解ActivityThread的main憋活,一直執(zhí)行到Activity的onCreate的過程岂津。