运用进程的发动流程
本文依据Android 11,首要剖析运用程序的发动流程,会直接定位到ActivityStackSupervisor.startSpecificActivity
函数开端,由于该函数前面的内容首要在Activity的发动流程中,能够经过这部分的文章来阅览。
看源码流程,需要骄傲自大,心态好。配合源码运用,主张先收藏,夜深人静,心血来潮再看。
经过剖析运用进程的发动流程,能够得到:
- 在Framework层,现在不止有AMS负责恳求Zygote进程创立新进程,还有
ATMS
、ActivityStarter
、ActivityTaskManger
、ActivityTaskS
在协助分担一些参数和逻辑的查看。 - 每个进程都是经过
fork Zygote
进程而来,且取得Java虚拟机。也便是说每一个运用进程都有自己的虚拟机。 - 运用进程是经过
Soket
去恳求Zygote
进程fork
自己的。 - 每个进程都有自己的
Binder
线程池用于IPC
。 - 每个运用进程的主线程在
ActivityThread
,其main
函数会创立音讯循环机制。
1、ActivityStackSupervisor.startSpecificActivity
ATMS
有一个ProcessMap<WindowProcessController>
类型的mProcessNames
,用于存储封装了已发动进程信息ProcessRecord
和窗口信息Windows
的WindowProcessController
实例。WindowProcessController
用于协调ActivityManger
办理ProcessReocrd
和WindwManger
办理WIndow
和Activity
的联系。
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
的实例,经过getProcessController
函数取得当时wpc
目标,判别当时发动运用进程是否发动wpc != null && wpc.hasThread()
,假如条件成立,则开端真实发动一个未发动过的Activity
,经过realStartActivityLocked
;条件不成立,则调用mService
的startProcessAsync
发动当时Activity
的所在的进程。即startSpecificActivity
函数是发动进程和发动Activity
的一个分界点。
2、ATMS.startProcessAsync
PooledLambda.obtainMessage
函数是Lambda的调用方式,表明调用ActivityManagerInternal
的startProcess
函数,后续则是其参数。并回来一个Message
目标,发给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
的内部类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
函数
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
函数,有几个重载函数,第一个调用。
在 !isolated
,判别了发动IntentFlag
是否后台运转,是的话,直接回绝。否则整理AMS
中发生过Crash
的进程(当时运用)。
剖析一:创立当时运用进程的描绘ProcessRecord
。
判别当时体系是否发动结束,未发动结束,将进程信息缓存到AMS
的mProcessesOnHold
中。
剖析二:调用了别的一个重载函数。
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传递进来是false,
if (!isolated) {
//从mProcessNames缓存获取,由于是初次创立,null
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
//判别要发动进程是否后台运转,直接return null
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
if (mService.mAppErrors.isBadProcessLocked(info)) {
return null;
}
} else {
//重置进程的crash状况,使其处于正常状况
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) {
// 剖析一、创立新的运用进程描绘ProcessRocrd
//内部会将自己添加到mProcessNames中
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
if (app == null) {
return null;
}
//此时三者都是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重载
再次调用别的一个重载函数。
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, String abiOverride) {
return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
false /* mountExtStorageFull */, abiOverride);
}
重载函数,这个重载函数处理逻辑很长,首要给前面创立的ProcessRecord
类型的app
设置各种特点。例如外部存储挂载形式,运用进程运转形式,abi
架构等等,其中包含最重要一点便是剖析一,确定要发动进程的的类名:android.app.ActivityThread
。剖析二,持续调用重载函数。
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);
//剖析一:确定要发动运用程序的类名
final String entryPoint = "android.app.ActivityThread";
//剖析二:调用别的一个重载函数
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
} catch (RuntimeException e) {
...
}
}
重载函数:也是设置一些特点,然后调用startProcess函数。
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
函数会依据hostingRecord
特点mHostingZygote
判别走不同的创立分支,前面创立运用默认值,所以走了else
分支。经过 Process.start
函数创立新的运用进程。
Process.start
的一路调用:
Process.start=>ZygoteProcess.start=>ZygoteState.start=>ZygoteState.startViaZygote
8、ZygoteState.startViaZygote
startViaZygote
函数,首要是将传递进来的参数拼接成成字符串和收集起来。其中processClass
是
private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
//依据传递进来的参数,拼接成字符串并收集到ArrayList<String>类型argsForZygote
//将作为新运用程序的主函数的参数
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
9、ZygoteState.openZygoteSocketIfNeeded
zygoteSendArgsAndGetResult
的第一个参数,调用了openZygoteSocketIfNeeded
函数。尝试树立与Socket
的衔接(假如之前未树立的话)。咱们知道Zygote
进程在创立的进程,会调用runSelectLoop
函数,创立Server
端的Socket
,一向等候来自AMS
的Client
端的Socket
创立进程恳求。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
//树立和Zygote的Socket衔接
attemptConnectionToPrimaryZygote();
//匹配abi的架构。在Zygote的创立对应四种形式:32,32_64和64,64_32
//32,64
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
//首要架构形式不配,匹配第二种 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
函数首要经过底层的LocalSocket
创立与Zygote
进程的Socket
衔接,并取得输入流zygoteInputStream
和输出流zygoteOutputWriter
。
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}
和Zygote
进程的Server
端Socket
树立衔接后,便是开端往Socket
写数据了。
10、attemptZygoteSendArgsAndGetResult
回到第8步骤用了zygoteSendArgsAndGetResult
函数,又调用了attemptZygoteSendArgsAndGetResult
函数。
zygoteSendArgsAndGetResult=>attemptZygoteSendArgsAndGetResult
11、attemptZygoteSendArgsAndGetResult
到这儿,经过Socket
的方式向Zygote
进程写进前面拼接好的参数,Zygote
在Server
端的Socket
接纳到数据之后,会履行创立动作。在回来的result.pid>=0
表明创立成功,并运转在新的进程。
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
的发动流程进程,调用了ZygoteInit
的main
函数,由于Zygote
是经过fork
本身来创立其他进程,所以需要依据传递进来的参数,进行判别是发动什么类型的进程,例如本身isPrimaryZygote=true
,或许SystemServer
进程。然后经过ZygoteServer.runSelectLoop
函数,等候其他进程恳求创立新的进程。
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进程
} 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=",依据参数得到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) {
//发动SystemServer进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
//循环等候AMS来恳求创立新的进程
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
//调用新的进程主函数
if (caller != null) {
caller.run();
}
}
13、ZygoteServer.runSelectLoo
这儿只关注ZygoteServer.runSelectLoop
函数,接受Socket
客户端数据。
/**
* 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
首要是从循环中检测是否有衔接树立,树立之后履行ZygoteConnection
的processOneCommand
函数,并回来一个Runable
类型的command
目标。
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
args = Zygote.readArgumentList(mSocketReader);
//依据参数内容,作其他类型的处理
...
//创立进程,调用底层nativeForkAndSpecialize办法,经过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.mIsTopApp,
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
...
if (pid == 0) {
//设置mIsForkChild=true
zygoteServer.setForkChild();
//封闭Socket衔接
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//履行子进程内容
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
}
...
}
15、handleChildProc
handleChildProc
函数。
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();//为新进程创立Binder线程池
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
曾经还以为每个进程共用一个Binder
线程池,现在知道每个进程都有自己的Binder
线程池进行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
客户端传递下来的android.app.ActivityThread
。
18、RuntimeInit.findStaticMain
RuntimeInit.findStaticMain
函数首要经过反射创立ActivityThread
类的实例,并反射主函数main
,然后封装到MethodAndArgsCaller
实例中回来。
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
函数,调用主函数办法。
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
函数办法栈一路回来到runSelectLoop
函数,由于mIsForkChild
是true
,所以MethodAndArgsCaller
目标回来到ZygoteInit
的main
函数,并赋值给caller
变量。main
函数最终调用caller的run
函数。即履行了ActivityThread
的主函数main
。
本来自己还有个疑问,fork
子进程之后,并caller
的run
函数,已经退出了Zygote
进程的runSelectLoop
循环等候。怎么持续去接纳AMS
新的恳求。本来如此,fork
子进程后,后续的代码都运转在了子进程,这儿return
其实是子进程了。
一个进程调用fork()
函数后,体系先给新的进程分配资源,例如存储数据和代码的空间。然后把本来的进程的所有值都复制到新的新进程中,只要少数值与本来的进程的值不同。相当于克隆了一个自己。
19、进程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
的主函数,创立了ActivityThread
进程,并发动了音讯循环队列,代表着当时进程的主线程已发动。
知识点
-
fork
函数。 - 经过
Socket
创立新的进程。 - Binder机制和运用程序创立的机遇。
-
ActivityThread
的进程的主线程。
疑问点
- 经过
Zygote
进程fork
而来的子进程都会取得Zygote
创立的Java
虚拟机,也便是每个运用进程都有自己的Java
虚拟机。 - 每个运用进程都有归于自己的
Binder
线程池和音讯循环机制。 - 之所以
fork Zygote
进程而不是init
进程,是防止重复初始化环境资源的加载和虚拟机的创立。 - 进程的创立之所挑选Socket机制进行,由于Binder机制会导致死锁,怕父进程binder线程有锁,然后子进程的主线程一向在等其子线程(从父进程复制过来的子进程)的资源,可是其实父进程的子进程并没有被复制过来,形成死锁,所以fork不允许存在多线程。