在上一篇《Zygote啟動(dòng)流程》中已經(jīng)了解到硅急,ZygoteInit.java的main函數(shù)中會(huì)去創(chuàng)建ServerSocket时甚,創(chuàng)建應(yīng)用進(jìn)程時(shí)泻仙,AMS會(huì)連接ServerSocket發(fā)起創(chuàng)建進(jìn)程的請(qǐng)求屑那。因此AMS是Socket Client端拱镐,Zygote是Socket Server端艘款,創(chuàng)建進(jìn)程時(shí),Client連接Server端發(fā)起創(chuàng)建進(jìn)程的請(qǐng)求沃琅。
一哗咆、Client端(AMS)
首先來(lái)了解下AMS發(fā)起創(chuàng)建進(jìn)程請(qǐng)求的流程,以下是流程時(shí)序圖益眉。
在調(diào)用AMS的
startProcessLocked
函數(shù)來(lái)向Zygote發(fā)起fork進(jìn)程的求情晌柬,在AMS中startProcessLocked
函數(shù)最終會(huì)調(diào)用startProcess
函數(shù),首先看下startProcess
函數(shù)郭脂。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
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) {
try {
......
final ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
......
} else {
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});
}
......
} finally {
......
}
}
startProcess
函數(shù)接著會(huì)調(diào)用Process的start
函數(shù)來(lái)發(fā)起fork進(jìn)程請(qǐng)求年碘,接下來(lái)研究下Process的start
函數(shù)。
/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 zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
Process的start
函數(shù)又跳轉(zhuǎn)到ZygoteProcess.start
函數(shù)朱庆。
/frameworks/base/core/java/android/os/ZygoteProcess.java
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,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
......
}
}
繼續(xù)跳轉(zhuǎn)到startViaZygote
函數(shù)
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,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
.....
//初始化進(jìn)程的啟動(dòng)參數(shù)列表argsForZygote邏輯
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
接下來(lái)先看下openZygoteSocketIfNeeded
函數(shù)盛泡,該函數(shù)主要是調(diào)用ZygoteState.connect
函數(shù)連接ZygoteInit.main
函數(shù)中創(chuàng)建的ServerSocket,這個(gè)在《Zygote啟動(dòng)流程》中已經(jīng)說(shuō)過(guò)娱颊,ZygoteState就是ZygoteProcess的一個(gè)靜態(tài)內(nèi)部類傲诵,主要是維持Zygote進(jìn)程socket服務(wù)的連接邏輯,ZygoteState.connet函數(shù)也是連接socket箱硕。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} 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);
}
再看下zygoteSendArgsAndGetResult函數(shù)拴竹。
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
......
//將要?jiǎng)?chuàng)建的應(yīng)用進(jìn)程啟動(dòng)參數(shù)傳給ZygoteState對(duì)象中
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
//通過(guò)Socket讀取Zygote建成功的進(jìn)程PID
// Socket 對(duì)端的請(qǐng)求在 ZygoteInit.runSelectLoop中進(jìn)行處理
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
二、Server端(Zygote)
AMS發(fā)起創(chuàng)建進(jìn)程請(qǐng)求剧罩,Zygote端接受請(qǐng)求的流程栓拜。《Zygote啟動(dòng)流程》中已經(jīng)分析了ZygoteInit.main
函數(shù)會(huì)創(chuàng)建ServerSocket惠昔,且在ZygoteServer.java.runSelectLoop
等待AMS連接和發(fā)起請(qǐng)求幕与。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
......
try {
......
//創(chuàng)建Server Socket
zygoteServer.registerServerSocketFromEnv(socketName);
......
//等待AMS socket連接,請(qǐng)求fork新進(jìn)程
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
......
}
ZygoteInit.main
函數(shù)中會(huì)調(diào)用zygoteServer.registerServerSocketFromEnv
創(chuàng)建一個(gè)LocalServerSocket對(duì)象镇防,該對(duì)象封裝了ServerSocket邏輯啦鸣。 zygoteServer.runSelectLoop(abiList)
函數(shù)會(huì)調(diào)用LocalServerSocket.accept函數(shù)和ZygoteConnection.processOneCommand
函數(shù),accept函數(shù)等待客戶端的連接来氧,processOneCommand函數(shù)處理fork進(jìn)程邏輯诫给,這個(gè)在《Zygote啟動(dòng)流程》已經(jīng)了解過(guò)。
ZygoteConnection.processOneCommand
函數(shù)主要執(zhí)行這三個(gè)操作:
- 1.調(diào)用 Zygote.forkAndSpecialize 進(jìn)行進(jìn)程復(fù)制操作
- 2.調(diào)用 handleChildProc 處理新建進(jìn)程資源初始化啦扬,如創(chuàng)建 Binder 線程池中狂,啟動(dòng)一個(gè)主線程消息隊(duì)列
- 3.調(diào)用 handleParentProc 將新建進(jìn)程的 PID 返回給 system_server,表示創(chuàng)建結(jié)果扑毡。
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
......
//fork 進(jìn)程胃榕,
//pid == 0:新進(jìn)程,調(diào)用handleChildProc
//pid != 0:當(dāng)前進(jìn)程瞄摊,調(diào)用handleParentProc
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
// 創(chuàng)建出的新進(jìn)程
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();//關(guān)閉socket
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
// 父進(jìn)程將在這里進(jìn)行處理
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
......
}
}
Zygote.forkAndSpecialize
函數(shù)>Zygote.forkAndSpecialize
>Zygote.nativeForkAndSpecialize
來(lái)fork進(jìn)程勤晚。
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) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
......
}
fork進(jìn)程返回pid == 0則是新進(jìn)程枉层,會(huì)調(diào)用zygoteServer.closeServerSocket();
關(guān)閉socket,還會(huì)調(diào)用handleChildProc
函數(shù)執(zhí)行ZygoteInit.zygoteInit()
赐写。
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
closeSocket();
......
if (parsedArgs.invokeWith != null) {
......
} else {
if (!isZygote) {// 新建應(yīng)用進(jìn)程時(shí)isZygote=false
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
ZygoteInit.zygoteInit()
主要邏輯:
- 1.nativeZygoteInit啟動(dòng)App進(jìn)程的Binder線程池
- 2.applicationInit反射執(zhí)行
ActivityThread.main
函數(shù)
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
......
ZygoteInit.nativeZygoteInit();//初始化Binder線程
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
RuntimeInit.applicationInit
>RuntimeInit.findStaticMain
>RuntimeInit.MethodAndArgsCaller
就是利用反射調(diào)用main函數(shù)鸟蜡。
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
......
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
......
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
......
}
}
}
我們來(lái)驗(yàn)證下,可以在Activity.onCreate
函數(shù)中執(zhí)行Log.d(TAG, Log.getStackTraceString(new Throwable()));
函數(shù)打印堆棧挺邀。
堆棧順序:
ZygoteInit.main
>ZygoteInit$MethodAndArgsCaller.run
>Method.invoke
>ActivityThread.main
該堆棧跟分析的流程一致揉忘。代碼如下:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "[lynnlee]";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, Log.getStackTraceString(new Throwable()));
}
}
ActivityOncreate函數(shù)打印堆棧結(jié)果:
com.lynnlee.myapplication D/[lynnlee]: java.lang.Throwable
at com.lynnlee.myapplication.MainActivity.onCreate(MainActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6309)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1114)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2467)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2574)
at android.app.ActivityThread.access$1000(ActivityThread.java:166)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1411)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5563)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:737)
參考資料
https://blog.csdn.net/weixin_34335458/article/details/87992608
《Android進(jìn)階解密》