Android?應(yīng)用程序的啟動(dòng)流程示例詳解
應(yīng)用進(jìn)程的啟動(dòng)流程
本文基于Android 11,主要分析應(yīng)用程序的啟動(dòng)流程,會(huì)直接定位到ActivityStackSupervisor.startSpecificActivity函數(shù)開(kāi)始,因?yàn)樵摵瘮?shù)前面的內(nèi)容主要在Activity的啟動(dòng)流程中,可以通過(guò)這部分的文章來(lái)閱讀。
看源碼流程,需要戒驕戒躁,心態(tài)好。配合源碼使用,建議先收藏,夜深人靜,心血來(lái)潮再看。
通過(guò)分析應(yīng)用進(jìn)程的啟動(dòng)流程,可以得到:
- 在Framework層,現(xiàn)在不止有AMS負(fù)責(zé)請(qǐng)求Zygote進(jìn)程創(chuàng)建新進(jìn)程,還有ATMS、ActivityStarter、ActivityTaskManger、ActivityTaskS在協(xié)助分擔(dān)一些參數(shù)和邏輯的檢查。
- 每個(gè)進(jìn)程都是通過(guò)fork Zygote進(jìn)程而來(lái),且獲得Java虛擬機(jī)。也就是說(shuō)每一個(gè)應(yīng)用進(jìn)程都有自己的虛擬機(jī)。
- 應(yīng)用進(jìn)程是通過(guò)Soket去請(qǐng)求Zygote進(jìn)程fork自己的。
- 每個(gè)進(jìn)程都有自己的Binder線程池用于IPC。
- 每個(gè)應(yīng)用進(jìn)程的主線程在ActivityThread,其main函數(shù)會(huì)創(chuàng)建消息循環(huán)機(jī)制。
1、ActivityStackSupervisor.startSpecificActivity
ATMS有一個(gè)ProcessMap<WindowProcessController>類型的mProcessNames ,用于存儲(chǔ)封裝了已啟動(dòng)進(jìn)程信息ProcessRecord和窗口信息Windows的WindowProcessController實(shí)例。WindowProcessController用于協(xié)調(diào)ActivityManger管理ProcessReocrd和WindwManger管理WIndow和Activity的關(guān)系。
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
...
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
這里的mService是ActivityTaskManagerService的實(shí)例,通過(guò)getProcessController函數(shù)獲得當(dāng)前wpc對(duì)象,判斷當(dāng)前啟動(dòng)應(yīng)用進(jìn)程是否啟動(dòng)wpc != null && wpc.hasThread(),如果條件成立,則開(kāi)始真正啟動(dòng)一個(gè)未啟動(dòng)過(guò)的Activity,通過(guò)realStartActivityLocked;條件不成立,則調(diào)用mService的startProcessAsync啟動(dòng)當(dāng)前Activity的所在的進(jìn)程。即startSpecificActivity函數(shù)是啟動(dòng)進(jìn)程和啟動(dòng)Activity的一個(gè)分界點(diǎn)。
2、ATMS.startProcessAsync
PooledLambda.obtainMessage函數(shù)是Lambda的調(diào)用方式,表示調(diào)用ActivityManagerInternal的startProcess函數(shù),后續(xù)則是其參數(shù)。并返回一個(gè)Message對(duì)象,發(fā)給Handler類型的mH。
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
}
抽象類ActivityManagerInternal的繼承類定義在ActivityManagerService的內(nèi)部類LocalService。
public final class LocalService extends ActivityManagerInternal
3、LocalService.startProcess
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */, true /* keepIfLarge */);
}
4、startProcessLocked函數(shù)
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
keepIfLarge, null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
5、ProcessList.startProcessLocked
ProcessList類的startProcessLocked函數(shù),有幾個(gè)重載函數(shù),第一個(gè)調(diào)用。
在 !isolated,判斷了啟動(dòng)IntentFlag是否后臺(tái)運(yùn)行,是的話,直接拒絕。否則清理AMS中發(fā)生過(guò)Crash的進(jìn)程(當(dāng)前應(yīng)用)。
分析一:創(chuàng)立當(dāng)前應(yīng)用進(jìn)程的描述ProcessRecord。
判斷當(dāng)前系統(tǒng)是否啟動(dòng)完畢,未啟動(dòng)完畢,將進(jìn)程信息緩存到AMS的mProcessesOnHold中。
分析二:調(diào)用了另外一個(gè)重載函數(shù)。
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
Runnable crashHandler) {
long startTime = SystemClock.uptimeMillis();
ProcessRecord app;
//isolated傳遞進(jìn)來(lái)是false,
if (!isolated) {
//從mProcessNames緩存獲取,由于是首次創(chuàng)建,null
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
//判斷要啟動(dòng)進(jìn)程是否后臺(tái)運(yùn)行,直接return null
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
if (mService.mAppErrors.isBadProcessLocked(info)) {
return null;
}
} else {
//重置進(jìn)程的crash狀態(tài),使其處于正常狀態(tài)
mService.mAppErrors.resetProcessCrashTimeLocked(info);
if (mService.mAppErrors.isBadProcessLocked(info)) {
mService.mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
app = null;
}
ProcessRecord precedence = null;
if (app != null && app.pid > 0) {
if ((!knownToBeDead && !app.killed) || app.thread == null) {
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
return app;
}
ProcessList.killProcessGroup(app.uid, app.pid);
precedence = app;
app = null;
}
if (app == null) {
// 分析一、創(chuàng)建新的應(yīng)用進(jìn)程描述ProcessRocrd
//內(nèi)部會(huì)將自己添加到mProcessNames中
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
if (app == null) {
return null;
}
//此時(shí)三者都是null
app.crashHandler = crashHandler;
app.isolatedEntryPoint = entryPoint;
app.isolatedEntryPointArgs = entryPointArgs;
if (precedence != null) {
app.mPrecedence = precedence;
precedence.mSuccessor = app;
}
} else {
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
}
// If the system is not ready yet, then hold off on starting this
// process until it is.
if (!mService.mProcessesReady
&& !mService.isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mService.mProcessesOnHold.contains(app)) {
mService.mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
"System not ready, putting on hold: " + app);
checkSlow(startTime, "startProcess: returning with proc on hold");
return app;
}
分析二:
final boolean success =
startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
6、ProcessList.startProcessLocked重載
再次調(diào)用另外一個(gè)重載函數(shù)。
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, String abiOverride) {
return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
false /* mountExtStorageFull */, abiOverride);
}
重載函數(shù),這個(gè)重載函數(shù)處理邏輯很長(zhǎng),主要給前面創(chuàng)建的ProcessRecord類型的app設(shè)置各種屬性。例如外部存儲(chǔ)掛載模式,應(yīng)用進(jìn)程運(yùn)行模式,abi架構(gòu)等等,其中包括最重要一點(diǎn)就是分析一,確定要啟動(dòng)進(jìn)程的的類名:android.app.ActivityThread。分析二,繼續(xù)調(diào)用重載函數(shù)。
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
boolean mountExtStorageFull, String abiOverride) {
...
app.gids = gids;
app.setRequiredAbi(requiredAbi);
app.instructionSet = instructionSet;
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
//分析一:確定要啟動(dòng)應(yīng)用程序的類名
final String entryPoint = "android.app.ActivityThread";
//分析二:調(diào)用另外一個(gè)重載函數(shù)
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
} catch (RuntimeException e) {
...
}
}
重載函數(shù):也是設(shè)置一些屬性,然后調(diào)用startProcess函數(shù)。
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
...
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
...
}
}
7、ProcessList.startProcess
ProcessList類的startProcess函數(shù)會(huì)根據(jù)hostingRecord屬性mHostingZygote判斷走不同的創(chuàng)建分支,前面創(chuàng)建使用默認(rèn)值,所以走了else分支。通過(guò) Process.start函數(shù)創(chuàng)建新的應(yīng)用進(jìn)程。
Process.start的一路調(diào)用:
Process.start=>ZygoteProcess.start=>ZygoteState.start=>ZygoteState.startViaZygote
8、ZygoteState.startViaZygote
startViaZygote函數(shù),主要是將傳遞進(jìn)來(lái)的參數(shù)拼接成成字符串和收集起來(lái)。其中processClass是
private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
//根據(jù)傳遞進(jìn)來(lái)的參數(shù),拼接成字符串并收集到ArrayList<String>類型argsForZygote
//將作為新應(yīng)用程序的主函數(shù)的參數(shù)
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
9、ZygoteState.openZygoteSocketIfNeeded
zygoteSendArgsAndGetResult的第一個(gè)參數(shù),調(diào)用了openZygoteSocketIfNeeded函數(shù)。嘗試建立與Socket的連接(如果之前未建立的話)。我們知道Zygote進(jìn)程在創(chuàng)建的過(guò)程,會(huì)調(diào)用runSelectLoop函數(shù),創(chuàng)建Server端的Socket,一直等待來(lái)自AMS的Client端的Socket創(chuàng)建進(jìn)程請(qǐng)求。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
//建立和Zygote的Socket連接
attemptConnectionToPrimaryZygote();
//匹配abi的架構(gòu)。在Zygote的創(chuàng)建對(duì)應(yīng)四種模式:32,32_64和64,64_32
//32,64
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
//主要架構(gòu)模式不配,匹配第二種 32_64,64_32
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函數(shù)主要通過(guò)底層的LocalSocket創(chuàng)建與Zygote進(jìn)程的Socket連接,并獲得輸入流zygoteInputStream和輸出流zygoteOutputWriter。
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}
和Zygote進(jìn)程的Server端Socket建立連接后,就是開(kāi)始往Socket寫數(shù)據(jù)了。
10、attemptZygoteSendArgsAndGetResult
回到第8步調(diào)用了zygoteSendArgsAndGetResult函數(shù),又調(diào)用了attemptZygoteSendArgsAndGetResult函數(shù)。
zygoteSendArgsAndGetResult=>attemptZygoteSendArgsAndGetResult
11、attemptZygoteSendArgsAndGetResult
到這里,通過(guò)Socket的方式向Zygote進(jìn)程寫進(jìn)前面拼接好的參數(shù),Zygote在Server端的Socket接收到數(shù)據(jù)之后,會(huì)執(zhí)行創(chuàng)建動(dòng)作。在返回的result.pid>=0表示創(chuàng)建成功,并運(yùn)行在新的進(jìn)程。
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();
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);
}
}
12、Zygote.main
在Zygote的啟動(dòng)流程過(guò)程,調(diào)用了ZygoteInit的main函數(shù),因?yàn)閆ygote是通過(guò)fork自身來(lái)創(chuàng)建其他進(jìn)程,所以需要根據(jù)傳遞進(jìn)來(lái)的參數(shù),進(jìn)行判斷是啟動(dòng)什么類型的進(jìn)程,例如自身isPrimaryZygote=true,或者SystemServer進(jìn)程。然后通過(guò)ZygoteServer.runSelectLoop函數(shù),等待其他進(jìn)程請(qǐng)求創(chuàng)建新的進(jìn)程。
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
Runnable caller;
try {
...
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true; //判斷是否SystemServer進(jìn)程
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
//SCOKET_NAME_ARG="--socket-name=",根據(jù)參數(shù)得到SocketName
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
//PRIMARY_SOCKET_NAME=zygote
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
gcAndFinalize();
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//啟動(dòng)SystemServer進(jìn)程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
//循環(huán)等待AMS來(lái)請(qǐng)求創(chuàng)建新的進(jìn)程
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
//調(diào)用新的進(jìn)程主函數(shù)
if (caller != null) {
caller.run();
}
}
13、ZygoteServer.runSelectLoo
這里只關(guān)注ZygoteServer.runSelectLoop函數(shù),接受Socket客戶端數(shù)據(jù)。
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*/
Runnable runSelectLoop(String abiList) {
while (true) {
...
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
...
if (mIsForkChild) {
return command;
}
....
}
}
14、ZygoteConnection.processOneCommand
runSelctLoop主要是從循環(huán)中檢測(cè)是否有連接建立,建立之后執(zhí)行ZygoteConnection的processOneCommand函數(shù),并返回一個(gè)Runable類型的command對(duì)象。
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
args = Zygote.readArgumentList(mSocketReader);
//根據(jù)參數(shù)內(nèi)容,作其他類型的處理
...
//創(chuàng)建進(jìn)程,調(diào)用底層nativeForkAndSpecialize方法,通過(guò)fork當(dāng)前進(jìn)程來(lái)創(chuàng)建一個(gè)子線程。
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.mIsTopApp,
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
...
if (pid == 0) {
//設(shè)置mIsForkChild=true
zygoteServer.setForkChild();
//關(guān)閉Socket連接
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//執(zhí)行子進(jìn)程內(nèi)容
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
}
...
}
15、handleChildProc
handleChildProc函數(shù)。
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
...
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
16、 ZygoteInit.zygoteInit
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();//為新進(jìn)程創(chuàng)建Binder線程池
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
以前還以為每個(gè)進(jìn)程共用一個(gè)Binder線程池,現(xiàn)在知道每個(gè)進(jìn)程都有自己的Binder線程池進(jìn)行IPC。
17、RuntimeInit.applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
final Arguments args = new Arguments(argv);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
這里的args.startClass就是Socket客戶端傳遞下來(lái)的android.app.ActivityThread。
18、RuntimeInit.findStaticMain
RuntimeInit.findStaticMain函數(shù)主要通過(guò)反射創(chuàng)建ActivityThread類的實(shí)例,并反射主函數(shù)main,然后封裝到MethodAndArgsCaller實(shí)例中返回。
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
...
Class<?> cl = Class.forName(className, true, classLoader);
Method m = cl.getMethod("main", new Class[] { String[].class });
...
return new MethodAndArgsCaller(m, argv);
}
MethodAndArgsCaller類繼承自Runable,并在其run函數(shù),調(diào)用主函數(shù)方法。
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() {
...
mMethod.invoke(null, new Object[] { mArgs });
...
}
}
隨著findStaticMain函數(shù)方法棧一路返回到runSelectLoop函數(shù),因?yàn)閙IsForkChild是true,所以MethodAndArgsCaller對(duì)象返回到ZygoteInit的main函數(shù),并賦值給caller變量。main函數(shù)最后調(diào)用caller的run函數(shù)。即執(zhí)行了ActivityThread的主函數(shù)main。
本來(lái)自己還有個(gè)疑惑,fork子進(jìn)程之后,并caller的run函數(shù),已經(jīng)退出了Zygote進(jìn)程的runSelectLoop循環(huán)等待。怎么繼續(xù)去接收AMS新的請(qǐng)求。原來(lái)如此,fork子進(jìn)程后,后續(xù)的代碼都運(yùn)行在了子進(jìn)程,這里return其實(shí)是子進(jìn)程了。
一個(gè)進(jìn)程調(diào)用fork()函數(shù)后,系統(tǒng)先給新的進(jìn)程分配資源,例如存儲(chǔ)數(shù)據(jù)和代碼的空間。然后把原來(lái)的進(jìn)程的所有值都復(fù)制到新的新進(jìn)程中,只有少數(shù)值與原來(lái)的進(jìn)程的值不同。相當(dāng)于克隆了一個(gè)自己。
19、進(jìn)程ActivityThread.main。
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
ActivityThread的主函數(shù),創(chuàng)建了ActivityThread進(jìn)程,并啟動(dòng)了消息循環(huán)隊(duì)列,代表著當(dāng)前進(jìn)程的主線程已啟動(dòng)。
知識(shí)點(diǎn)
- fork函數(shù)。
- 通過(guò)Socket創(chuàng)建新的進(jìn)程。
- Binder機(jī)制和應(yīng)用程序創(chuàng)建的時(shí)機(jī)。
- ActivityThread的進(jìn)程的主線程。
疑問(wèn)點(diǎn)
- 通過(guò)Zygote進(jìn)程fork而來(lái)的子進(jìn)程都會(huì)獲得Zygote創(chuàng)建的Java虛擬機(jī),也就是每個(gè)應(yīng)用進(jìn)程都有自己的Java虛擬機(jī)。
- 每個(gè)應(yīng)用進(jìn)程都有屬于自己的Binder線程池和消息循環(huán)機(jī)制。
- 之所以fork Zygote進(jìn)程而不是init進(jìn)程,是避免重復(fù)初始化環(huán)境資源的加載和虛擬機(jī)的創(chuàng)建。
- 進(jìn)程的創(chuàng)建之所選擇Socket機(jī)制進(jìn)行,因?yàn)锽inder機(jī)制會(huì)導(dǎo)致死鎖,怕父進(jìn)程binder線程有鎖,然后子進(jìn)程的主線程一直在等其子線程(從父進(jìn)程拷貝過(guò)來(lái)的子進(jìn)程)的資源,但是其實(shí)父進(jìn)程的子進(jìn)程并沒(méi)有被拷貝過(guò)來(lái),造成死鎖,所以fork不允許存在多線程。
以上就是Android 應(yīng)用程序的啟動(dòng)流程示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android 程序啟動(dòng)流程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 詳解Android廣播Broadcast的啟動(dòng)流程
- Android?Service啟動(dòng)綁定流程詳解
- Android framework ATMS啟動(dòng)流程
- Android應(yīng)用啟動(dòng)白屏處理方案詳解
- Android基準(zhǔn)配置文件Baseline?Profile方案提升啟動(dòng)速度
- Android開(kāi)發(fā)InputManagerService創(chuàng)建與啟動(dòng)流程
- Android10 App啟動(dòng)Activity源碼分析
- Android10 App 啟動(dòng)分析進(jìn)程創(chuàng)建源碼解析
相關(guān)文章
Android自定義view實(shí)現(xiàn)阻尼效果的加載動(dòng)畫
這篇文章主要介紹了Android自定義view實(shí)現(xiàn)阻尼效果的加載動(dòng)畫的相關(guān)資料,非常不錯(cuò),具有一定的參考借鑒加載,需要的朋友可以參考下2016-11-11
Android實(shí)現(xiàn)跨進(jìn)程接口回掉的方法
這篇文章主要給大家介紹了關(guān)于Android如何實(shí)現(xiàn)跨進(jìn)程接口回掉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Android 10 啟動(dòng)Init進(jìn)程解析
這篇文章主要為大家介紹了Android 10 啟動(dòng)Init進(jìn)程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Android 仿高德地圖可拉伸的BottomSheet的示例代碼
這篇文章主要介紹了Android 仿高德地圖可拉伸的BottomSheet的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
詳解Android使用OKHttp3實(shí)現(xiàn)下載(斷點(diǎn)續(xù)傳、顯示進(jìn)度)
本篇文章主要介紹了詳解Android使用OKHttp3實(shí)現(xiàn)下載(斷點(diǎn)續(xù)傳、顯示進(jìn)度),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
android 拷貝sqlite數(shù)據(jù)庫(kù)到本地sd卡的方法
下面小編就為大家?guī)?lái)一篇android 拷貝sqlite數(shù)據(jù)庫(kù)到本地sd卡的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
Android開(kāi)發(fā)實(shí)例之多點(diǎn)觸控程序
本文主要介紹 Android開(kāi)發(fā)多點(diǎn)觸控,這里提供了詳細(xì)的資料和示例代碼,以及實(shí)現(xiàn)效果圖,有開(kāi)發(fā)Android應(yīng)用需要這樣的功能的小伙伴可以參考下2016-08-08
Android使用onCreateOptionsMenu()創(chuàng)建菜單Menu的方法詳解
這篇文章主要介紹了Android使用onCreateOptionsMenu()創(chuàng)建菜單Menu的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android基于onCreateOptionsMenu創(chuàng)建菜單的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2016-11-11
Android熱更新開(kāi)源項(xiàng)目Tinker集成實(shí)踐總結(jié)
最近項(xiàng)目集成了Tinker,開(kāi)始認(rèn)為集成會(huì)比較簡(jiǎn)單,但是在實(shí)際操作的過(guò)程中還是遇到了一些問(wèn)題,本文就會(huì)介紹在集成過(guò)程大家基本會(huì)遇到的主要問(wèn)題。下面跟著小編一起來(lái)看下吧2017-01-01

