商务网站的特点,苏州企业网站建设,大讲堂123专注网站模板制作,网址ip查询域名解析系列文章
Android S从桌面点击图标启动APP流程 (一)Android S从桌面点击图标启动APP流程 (二)
Android S从桌面点击图标启动APP流程 (三)
Android S从桌面点击图标启动APP流程 (四)
Android S从桌面点击图标启动APP流程 (五)
Android 12的源码链接#xff1a;
android 1…系列文章
Android S从桌面点击图标启动APP流程 (一)Android S从桌面点击图标启动APP流程 (二)
Android S从桌面点击图标启动APP流程 (三)
Android S从桌面点击图标启动APP流程 (四)
Android S从桌面点击图标启动APP流程 (五)
Android 12的源码链接
android 12 aosphttp://aospxref.com/android-12.0.0_r3/上文讲到了 Process.start, 这里接着往下讲解
ZygoteProcess#start
frameworks/base/core/java/android/os/ZygoteProcess.java public final Process.ProcessStartResult start(NonNull final String processClass,final String niceName,int uid, int gid, Nullable int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,Nullable String seInfo,NonNull String abi,Nullable String instructionSet,Nullable String appDataDir,Nullable String invokeWith,Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,Nullable long[] disabledCompatChanges,Nullable MapString, PairString, LongpkgDataInfoMap,Nullable MapString, PairString, LongallowlistedDataInfoList,boolean bindMountAppsData,boolean bindMountAppStorageDirs,Nullable String[] zygoteArgs) {// TODO (chriswailes): Is there a better place to check this value?if (fetchUsapPoolEnabledPropWithMinInterval()) {informZygotesOfUsapPoolStatus();}try {return startViaZygote(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, /*startChildZygote*/ false,packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,bindMountAppStorageDirs, zygoteArgs);} catch (ZygoteStartFailedEx ex) {Log.e(LOG_TAG,Starting VM process through Zygote failed);throw new RuntimeException(Starting VM process through Zygote failed, ex);}}
ZygoteProcess#startViaZygote
该过程主要工作是生成argsForZygote数组
frameworks/base/core/java/android/os/ZygoteProcess.java private Process.ProcessStartResult startViaZygote(NonNull final String processClass,Nullable final String niceName,final int uid, final int gid,Nullable final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,Nullable String seInfo,NonNull String abi,Nullable String instructionSet,Nullable String appDataDir,Nullable String invokeWith,boolean startChildZygote,Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,Nullable long[] disabledCompatChanges,Nullable MapString, PairString, LongpkgDataInfoMap,Nullable MapString, PairString, LongallowlistedDataInfoList,boolean bindMountAppsData,boolean bindMountAppStorageDirs,Nullable String[] extraArgs)throws ZygoteStartFailedEx {ArrayListString argsForZygote new ArrayList();// --runtime-args, --setuid, --setgid,// and --setgroups must go firstargsForZygote.add(--runtime-args);argsForZygote.add(--setuid uid);argsForZygote.add(--setgid gid);argsForZygote.add(--runtime-flags runtimeFlags);if (mountExternal Zygote.MOUNT_EXTERNAL_DEFAULT) {argsForZygote.add(--mount-external-default);} else if (mountExternal Zygote.MOUNT_EXTERNAL_INSTALLER) {argsForZygote.add(--mount-external-installer);} else if (mountExternal Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {argsForZygote.add(--mount-external-pass-through);} else if (mountExternal Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {argsForZygote.add(--mount-external-android-writable);}argsForZygote.add(--target-sdk-version targetSdkVersion);// --setgroups is a comma-separated listif (gids ! null gids.length 0) {final StringBuilder sb new StringBuilder();sb.append(--setgroups);final int sz gids.length;for (int i 0; i sz; i) {if (i ! 0) {sb.append(,);}sb.append(gids[i]);}argsForZygote.add(sb.toString());}if (niceName ! null) {argsForZygote.add(--nice-name niceName);}if (seInfo ! null) {argsForZygote.add(--seinfo seInfo);}if (instructionSet ! null) {argsForZygote.add(--instruction-set instructionSet);}if (appDataDir ! null) {argsForZygote.add(--app-data-dir appDataDir);}if (invokeWith ! null) {argsForZygote.add(--invoke-with);argsForZygote.add(invokeWith);}if (startChildZygote) {argsForZygote.add(--start-child-zygote);}if (packageName ! null) {argsForZygote.add(--package-name packageName);}if (isTopApp) {argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);}
......argsForZygote.add(processClass);if (extraArgs ! null) {Collections.addAll(argsForZygote, extraArgs);}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.
根据当前的abi来选择与zygote还是zygote64来进行通信。return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),zygotePolicyFlags,argsForZygote);}}
ZygoteProcess#zygoteSendArgsAndGetResult
这个方法的主要功能是通过socket通道向Zygote进程发送一个参数列表然后进入阻塞等待状态直到远端的socket服务端发送回来新创建的进程pid才返回。
frameworks/base/core/java/android/os/ZygoteProcess.java private Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, int zygotePolicyFlags, NonNull ArrayListString args)throws ZygoteStartFailedEx {// Throw early if any of the arguments are malformed. This means we can// avoid writing a partial response to the zygote.for (String arg : args) {// Making two indexOf calls here is faster than running a manually fused loop due// to the fact that indexOf is an optimized intrinsic.if (arg.indexOf(\n) 0) {throw new ZygoteStartFailedEx(Embedded newlines not allowed);} else if (arg.indexOf(\r) 0) {throw new ZygoteStartFailedEx(Embedded carriage returns not allowed);}}/** See com.android.internal.os.ZygoteArguments.parseArgs()* Presently the wire format to the zygote process is:* a) a count of arguments (argc, in essence)* b) a number of newline-separated argument strings equal to count** After the zygote process reads these it will write the pid of* the child or -1 on failure, followed by boolean to* indicate whether a wrapper process was used.*/String msgStr args.size() \n String.join(\n, args) \n;if (shouldAttemptUsapLaunch(zygotePolicyFlags, 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);}ZygoteProcess#attemptZygoteSendArgsAndGetResult
frameworks/base/core/java/android/os/ZygoteProcess.java 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();
等待socket服务端-zygote返回新创建的进程pid;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);}}
system_server进程通过调用attemptZygoteSendArgsAndGetResult()方法通过socket方式向Zygote进程发送消息这样会唤醒Zygote进程来响应socket客户端的请求即system_server端接下来的操作便是在Zygote来创建进程
ZygoteInit#main
然后会走进zygote进程创建进程由于步骤太多此处省略直接到ActivityThread.main这里开始讲解。后文接着讲ActivityThread#main