1、概述.
Android每启动一个应用程序就会新建一个进程,默认情况下,该应用程序的各个组件都会运行在同一个进程内, 但是在manifest中相应的组件的节点下配置android:process属性也可以运行在不同的进程。那么启动一个应用程 序是什么概念那?就是启动了一个activity或者service。此时假如是在新进程中启动的那么就回去创建这个进程。 进程创建完毕以后会启动一个主线程然后进入循环来处理UI界面消息,此线程也成为UI线程。 而我们又知道Android的应用程序是支持Binder通信的,binder它具有四个组件,分别是驱动程序、守护进程、 Client以及Server,其中Server组件在初始化时必须进入 一个循环中不断地与Binder驱动程序进行到交互,以便获 得Client组件发送的请求,这个进入循环的操作也是系统帮我们执行完毕的. 2、流程。 ActivityManagerService启动新的进程是从其成员函数startProcessLocked开始的.那么为什么就突然说是从这里 开始的那?其实等整理完毕Activity、service的启动流程就知道了,在启动它们的时候去判断是否是在一个新进程 中打开的,是的话就调用这个接口。至于怎么判断是不是在新进程打开的,也在service/Activity启动的文章中分析. 2.1、startProcessLocked() 位于AMS当中,有几个重载的方法,我们以一个外部的调用的接口为切入点. // 这个info也很关键啊,里面有很多的应用的信息,由外部传入的. final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { long startTime = SystemClock.elapsedRealtime(); ProcessRecord app;//ProcessRecord 用来记录这个进程打开的信息. if (!isolated) {//该进程是否是孤立的进程?暂发现大部分都是false,有一个是true. //keepIfLarge空间足够的时候是否保存?难道是这个意思吗? //一般的第一次走到这里返回的是null,由于以前没有创建过进程. app = getProcessRecordLocked(processName, info.uid, keepIfLarge); checkTime(startTime, "startProcess: after getProcessRecord"); } else { // If this is an isolated process, it can't re-use an existing process. app = null; } // We don't have to do anything more if: // (1) There is an existing application record; and // (2) The caller doesn't think it is dead, OR there is no thread // object attached to it so we know it couldn't have crashed; and // (3) There is a pid assigned to it, so it is either starting or // already running. if (app != null && app.pid > 0) {//当该进程已经存在的时候. if (!knownToBeDead || app.thread == null) { // We already have the app running, or are waiting for it to // come up (we have a pid but not yet its thread), so keep it. if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); // If this is a new package in the process, add the package to the list app.addPackage(info.packageName, info.versionCode, mProcessStats); checkTime(startTime, "startProcess: done, added package to proc"); return app;//不作处理返回. } // An application record is attached to a previous process, // clean it up now. if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); checkTime(startTime, "startProcess: bad proc running, killing"); Process.killProcessGroup(app.info.uid, app.pid); handleAppDiedLocked(app, true, true); checkTime(startTime, "startProcess: done killing old proc"); } String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null; if (!isolated) { if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { // If we are in the background, then check to see if this process // is bad. If so, we will just silently fail. if (mBadProcesses.get(info.processName, info.uid) != null) { if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid + "/" + info.processName); return null; } } else { // When the user is explicitly starting a process, then clear its // crash count so that we won't make it bad until they see at // least one crash dialog again, and make the process good again // if it had been bad. if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid + "/" + info.processName); mProcessCrashTimes.remove(info.processName, info.uid); if (mBadProcesses.get(info.processName, info.uid) != null) { EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, UserHandle.getUserId(info.uid), info.uid, info.processName); mBadProcesses.remove(info.processName, info.uid); if (app != null) { app.bad = false; } } } } if (app == null) {//以前没有启动过! checkTime(startTime, "startProcess: creating new process record"); //新建一个进程记录. app = newProcessRecordLocked(info, processName, isolated, isolatedUid); if (app == null) { Slog.w(TAG, "Failed making new process record for " + processName + "/" + info.uid + " isolated=" + isolated); return null; } app.crashHandler = crashHandler; //mProcessNames添加相应的赋值,这样下次get的时候就有了. mProcessNames.put(processName, app.uid, app); if (isolated) { mIsolatedProcesses.put(app.uid, app); } checkTime(startTime, "startProcess: done creating new process record"); } else { // If this is a new package in the process, add the package to the list app.addPackage(info.packageName, info.versionCode, mProcessStats); checkTime(startTime, "startProcess: added package to existing proc"); } // If the system is not ready yet, then hold off on starting this // process until it is. if (!mProcessesReady //等系统完全启动起来再说,先放到了mProcessesOnHold. && !isAllowedWhileBooting(info) && !allowWhileBooting) { if (!mProcessesOnHold.contains(app)) { mProcessesOnHold.add(app); } if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); checkTime(startTime, "startProcess: returning with proc on hold"); return app; } checkTime(startTime, "startProcess: stepping in to startProcess"); //最终又是调用重载的相关方法,进行进一步的处理. startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); checkTime(startTime, "startProcess: done starting proc!"); //从上面的函数返回时,app已经有pid了. return (app.pid != 0) ? app : null; } 关键的信息和参数有传入的:Application info 里面包含了很多的应用的信息,用于我么你初始化这个进程 ,isSolated从Log看大部分都是传入的false.先是通过getProcessRecordLocked来尝试获取一下已经存在的进程 记录,如果该记录没有存在的话就返回null,此时是第一次那么肯定会返回null. //z获取已经存在的进程的记录. final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { if (uid == Process.SYSTEM_UID) { ......//系统进程的一些处理. } ProcessRecord proc = mProcessNames.get(processName, uid);//还没往里面添加所以返回null. if (false && proc != null && !keepIfLarge && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && proc.lastCachedPss >= 4000) { .....//肯定不会走. } else if (proc != null && !keepIfLarge && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { ......//如果有crash的就杀死这个进程. } return proc;//返回查询到的进程. } mProcessNames是ProcessMap的类型,是一种封装的SparseArray,通过name和uid两个判断条件来获得Proce ss Record.回到startProcessLocked当中,如果以前确实没有启动过,没有相关的进程记录,接下来就是调用 newProcessRecordLocked()来为当前应用进程新建一 个ProcessRecord. //新建一个进程记录ProcessRecord. final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid) { //customProcess没有指定的时候,就会info.processName String proc = customProcess != null ? customProcess : info.processName; ..... int uid = info.uid; if (isolated) { if (isolatedUid == 0) { int userId = UserHandle.getUserId(uid); int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; while (true) { ...... } } else { // Special case for startIsolatedProcess (internal only), where // the uid of the isolated process is specified by the caller. uid = isolatedUid; } } return new ProcessRecord(stats, info, proc, uid); } 最主要得就是最后一句new ProcessRecord().去实例化了一个 ProcessRecord对象,注意此时这个对象很 多成员参数都还没赋值,比如它的关键变量int pid、IApplicationThread thread等,但此处传入一个很重 要的变量final ApplicationInfo info.在构造中实例化了它,然后通过这个成员变量获取应用的信息.再次 回到 startProcessLocked当中.就是调用另外一个重载的startProcessLocked去进一步做处理了. private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { long startTime = SystemClock.elapsedRealtime(); if (app.pid > 0 && app.pid != MY_PID) { .....//此情景下由于还没有初始化pid所以pid肯定不大于0. } ...... try { //看样子是设置组件的存活状态. 第三个参数是true,代表存活. AppGlobals.getPackageManager().setPackageAliveState(app.info.packageName, app.processName, true, UserHandle.getUserId(app.uid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { } try { int uid = app.uid; int[] gids = null; int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; if (!app.isolated) {//传入的相关参数是false. int[] permGids = null; try { checkTime(startTime, "startProcess: getting gids from package manager"); final PackageManager pm = mContext.getPackageManager(); permGids = pm.getPackageGids(app.info.packageName); ...... } catch (PackageManager.NameNotFoundException e) { } /* * Add shared application and profile GIDs so applications can share some * resources like shared libraries and access user-wide resources */ if (permGids == null) { gids = new int[2]; } else { gids = new int[permGids.length + 2]; System.arraycopy(permGids, 0, gids, 2, permGids.length); } gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); } checkTime(startTime, "startProcess: building args"); ...... int debugFlags = 0; ......//设置一些 debugFlags方便调试. app.gids = gids; app.requiredAbi = requiredAbi; app.instructionSet = instructionSet; // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; checkTime(startTime, "startProcess: asking zygote to start proc"); //注意一下这个返回值的类型!! Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); //执行完Process.start()以后此时app.pid还未赋值.、 //从zygote进程返回了. checkTime(startTime, "startProcess: returned from zygote!"); ...... if (app.persistent) { Watchdog.getInstance().processStarted(app.processName, startResult.pid); } app.setPid(startResult.pid);//根据从zygote进程取回来的结果对app.pia进行相关的赋值. ...... synchronized (mPidsSelfLocked) { //注意在这把pid加入到mPidsSelfLocked this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, startResult.usingWrapper ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } checkTime(startTime, "startProcess: done updating pids map"); if ("activity".equals(hostingType) || "service".equals(hostingType)) { mActivityTrigger.activityStartProcessTrigger(app.processName, startResult.pid); } } catch (RuntimeException e) { app.setPid(0);//启动失败的时候设置pid为值为0 ...... } } 受限制的一提的是它的entryPoint一般情况下都是"android.app.ActivityThread",直接是进程刚启动完 毕后将要执行的类的main函数所在的地方.代表一个主线程.注意此时Process.start()的返回值类型,它是 Process.ProcessStartResult public static final class ProcessStartResult { /** * The PID of the newly started process. * Always >= 0. (If the start failed, an exception will have been thrown instead.) */ public int pid; /** * True if the process was started with a wrapper attached. */ public boolean usingWrapper; } 我们需要重点关注的就是它的pid,它就是从zygote进程读回来的值,以供接下来的赋值处理.接下来分析 Process中的start()函数的处理. public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, zygoteArgs); } catch (ZygoteStartFailedEx ex) { } } 就是直接调用内部函数startViaZygote() (via:通过). private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { ArrayList<String> argsForZygote = new ArrayList<String>(); // --runtime-init, --setuid=, --setgid=, // and --setgroups= must go first //下面是创建进程的时候的各个参数 //如参数"--runtime-init"表示要为新创建的进程初始化运行时库 argsForZygote.add("--runtime-init"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) { argsForZygote.add("--enable-jni-logging"); } if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) { argsForZygote.add("--enable-safemode"); } if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) { argsForZygote.add("--enable-debugger"); } if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) { argsForZygote.add("--enable-checkjni"); } if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) { argsForZygote.add("--enable-assert"); } if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER) { argsForZygote.add("--mount-external-multiuser"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL) { argsForZygote.add("--mount-external-multiuser-all"); } argsForZygote.add("--target-sdk-version=" + targetSdkVersion); //TODO optionally enable debuger //argsForZygote.add("--enable-debugger"); // --setgroups is a comma-separated list if (gids != null && gids.length > 0) { StringBuilder sb = new StringBuilder(); sb.append("--setgroups="); 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); } argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } //把各个参数组装好 android.util.Log.d("zy_pro","openZygoteSocketIfNeeded abi = "+abi); return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } argsForZygote集合里面根据条件添加了各种的要传给zygote进程的参数.第一个就是"--runtime-init".每 个参数的具体用意,应该是linux中fork进程时的参数.zygoteSendArgsAndGetResult(..),有两个参数,第一 个是ZygoteState、第二个ArrayList的集合.ZygoteState:描述当前进程和zygote进程交互的状态.内部有输入 、输出流、LocalSocket当成员变量和一些connect、close的方法等. LocalSocket用于创建一个不是服务端的 位于Unix命名空间下的Socket. 下面我们先看是如何获取 ZygoteState的 private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);//ZYGOTE_SOCKET = "zygote" } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } // The primary zygote didn't match. Try the secondary. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { //ZYGOTE_SOCKET = "zygote_secondary" secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } } if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState; } //最多尝试了两次,还不行就抛出异常. throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); } primaryZygoteState是一个ZygoteState类型的变量,通过connect来创建一个socket,address = "zygote" 回到zygoteSendArgsAndGetResult当中. private static ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx { try { /** * See com.android.internal.os.ZygoteInit.readArgumentList() * 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. */ final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; writer.write(Integer.toString(args.size())); writer.newLine(); int sz = args.size(); for (int i = 0; i < sz; i++) { String arg = args.get(i); android.util.Log.d("zy_pro","Process arg = "+arg); if (arg.indexOf('\n') >= 0) { throw new ZygoteStartFailedEx( "embedded newlines not allowed"); } writer.write(arg); writer.newLine(); } writer.flush();//所有命令发送完毕 // Should there be a timeout on this? ProcessStartResult result = new ProcessStartResult(); result.pid = inputStream.readInt(); android.util.Log.d("zy_pro","Process result.pid = "+result.pid); if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } result.usingWrapper = inputStream.readBoolean(); android.util.Log.d("zy_pro","Process result.usingWrapper = "+result.usingWrapper); return result; } catch (IOException ex) { zygoteState.close(); throw new ZygoteStartFailedEx(ex); } } 通过zygoteState.writer的输出流往Socket中写入命令.最后通过result.pid = inputStream.readInt()来 读 取zygote进程创建完毕后的返回的进程的pid的值.不过注意最后的是Process.ProcessStartResult对象. 在这里有一个疑惑?由于自身对socket的不了解.不明白为什么此处要用个socket,直接调用函数不行?暂 时有课自欺欺人的认知,此处是算AMS所在的进程比如是"system"进程,它要去请求zygote进程去创建应用进程 那么这就涉及到了进程通信,此处就用的socket来进行的进程通信.在socket流中有数据的时候读出来.(为什么 不用binder那?应该是这种情况不是很合适吧?具体原理也不清楚) 至此我们应该去哪看这个socket的另一端那?注释里面已经很清楚了.在com.android.internal.os.Zygote Init .readArgumentList()当中.我们先去ZygoteInit当中看看.搜索以后发现并没有 readArgumentList.其实它是 在ZygoteConnection.java当中。而出发条件确实在 ZygoteInit中的runSelectLoop()在这个方法里面会循环监听 前面的socket的请求 .我们先来看一下ZygoteInit文件的main函数 public static void main(String argv[]) {//当fork一个zygote进程时,会进入. try { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = 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)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } registerZygoteSocket(socketName);//注册这个socket address = "zygote" EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); // Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gc(); // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. Trace.setTracingEnabled(false); if (startSystemServer) { startSystemServer(abiList, socketName); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(abiList);//循环去监听. closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run();// 调用对于ActivityThread的main函数的时候的异常最终到了这里. } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } } 注意当init进程fork一个zygote进程的时候最后会调用到这个文件的main函数当中,道理同ActivityThread.那么此时当前文 件是运行在zygote进程的,也就是AMS所在的进程要向这个zygote进程请它再去创建进程,这就是一个跨进程通信.在这个main函 数当中注册了socket,等待AMS的请求.接下来看看runSelectLoop. private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { //等待请求 ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); FileDescriptor[] fdArray = new FileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor()); peers.add(null); int loopCount = GC_LOOP_COUNT; while (true) { int index; /* * Call gc() before we block in select(). * It's work that has to be done anyway, and it's better * to avoid making every child do it. It will also * madvise() any free memory as a side-effect. * * Don't call it every time, because walking the entire * heap is a lot of overhead to free a few hundred bytes. */ if (loopCount <= 0) { gc(); loopCount = GC_LOOP_COUNT; } else { loopCount--; } try { fdArray = fds.toArray(fdArray); index = selectReadable(fdArray); } catch (IOException ex) { throw new RuntimeException("Error in select()", ex); } if (index < 0) { throw new RuntimeException("Error in select()"); } else if (index == 0) { ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDescriptor()); } else { boolean done; //zy 当将数据通过Socket接口发送出去后走到这里. //从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接 done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } } } } peers中存放的是ZygoteConnection,最终走到else分支调用done = peers.get(index).runOnce().调用 ZygoteConnection的 runOnce()此时还是在zygote的进程当中哦. boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; long startTime = SystemClock.elapsedRealtime(); try { //这不就对应到前面的注释了嘛. args = readArgumentList();//通过socket去读取写入到socket中的command descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { ...... } ...... int pid = -1; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; try { parsedArgs = new Arguments(args); ...... FileDescriptor fd = mSocket.getFileDescriptor(); ...... //下面是真正创建进程的地方. pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, parsedArgs.appDataDir); checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize"); } catch (IOException ex) { ..... } catch ( ZygoteSecurityException ex ) { } try { if (pid == 0) {//子进程 // in child IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); // should never get here, the child is expected to either // throw ZygoteInit.MethodAndArgsCaller or exec(). return true; } else {//父进程当中. // in parent...pid of < 0 means failure IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } } 先是调用readArgumentList()读取命令参数. /** * Reads an argument list from the command socket/ * @return Argument list or null if EOF is reached * @throws IOException passed straight through */ private String[] readArgumentList() throws IOException { /** * See android.os.Process.zygoteSendArgsAndGetPid() * 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. */ int argc; try { String s = mSocketReader.readLine(); if (s == null) { // EOF reached. return null; } argc = Integer.parseInt(s); } catch (NumberFormatException ex) { Log.e(TAG, "invalid Zygote wire format: non-int at argc"); throw new IOException("invalid wire format"); } // See bug 1092107: large argc can be used for a DOS attack if (argc > MAX_ZYGOTE_ARGC) { throw new IOException("max arg count exceeded"); } String[] result = new String[argc]; for (int i = 0; i < argc; i++) { result[i] = mSocketReader.readLine(); if (result[i] == null) { // We got an unexpected EOF. throw new IOException("truncated request"); } } return result; } 然后就是调用zygote的forkAndSpecialize.来实现真正的进程的创建,这个函数执行完后 创建一个新进程,而且有两个返回 值,一个是在当前进程中返回的,一个是在新创建的进程中返回,即在当前进程的子进程中返回。 在当前进程中的返回值就是新 创建的子进程的pid值,而在子进程中的返回值是0。(就当成fork出来的进程一模一样,然后函数就走到这里了,从这里往下执 行). public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, String instructionSet, String appDataDir) { ...... int pid = nativeForkAndSpecialize( //直接调用到了native层的方法. uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, instructionSet, appDataDir); ...... return pid; } 直接调用了native的方法,此处就是返回两个返回值的地方了. native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, String instructionSet, String appDataDir); 回到ZygoteConnecttion的runOnce()方法当中 pid = Zygote.forkAndSpecialize(...)接着往下执行. 我们先分析新建的这个进程的流程,也就是pid返回为0的这个分支。此时位于我们创建的子进程当中.执行handleChildProc private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { /** * By the time we get here, the native code has closed the two actual Zygote * socket connections, and substituted /dev/null in their place. The LocalSocket * objects still need to be closed properly. */ closeSocket(); ZygoteInit.closeServerSocket();//先关闭socket if (descriptors != null) { ...... } if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } if (parsedArgs.runtimeInit) {//前面第一个放入的就是这个 if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, pipeFd, parsedArgs.remainingArgs); } else { RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } } else { ...... } } 最终调用到RuntimeInit.java中的zygoteInit方法,我们进去看一下 public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {//zy if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); redirectLogStreams(); commonInit(); nativeZygoteInit();//执行Binder驱动程序初始化的相关工作了,服务端可以循环监听. //进程创建完毕,调用argv对应类的入口的main函数."android.app.ActivityThread" applicationInit(targetSdkVersion, argv, classLoader); } 最主要的就是两个方法,第一个nativeZygoteInit,该方法执行了该进程的Binder相关的初始化工作。其实就是建立了binder线程 池来循环监听客户端的binder通信请求.最终通过nativeZygoteInit放调用到了AndroidRuntime.cpp中的com_android_internal_ os_R un timeInit_nativeZygoteInit,然后又调用到了app_main.cpp中的 onZygoteInit virtual void onZygoteInit() { // Re-enable tracing now that we're no longer in Zygote. atrace_set_tracing_enabled(true); sp<ProcessState> proc = ProcessState::self();//看到了开启循环,然后一直和binder驱动打交道,监听客户端的请求. ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); } s erver组件在初始化时必须进入一个循环中不断地与Binder驱动程序进行到交互,以便获得Client组件发送的请 求 进入一个无限循环中与Binder驱动程序交互以便获得Client端的请求.通过以上方法调用,完成了假如它作为服务 端的时候的binder的支持.(也就是native层实现binder的最后两步) 至此完成了对binder通信的支持,解析来就是分析applicationInit(targetSdkVersion, argv, classLoader)的调用了.它那其 实最终就是执行了我们前面传入的entrypoint = "android.app.ActivityThread"对应的main函数. private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { ...... final Arguments args; try { args = new Arguments(argv); } catch (IllegalArgumentException ex) { Slog.e(TAG, ex.getMessage()); // let the process exit return; } // Remaining arguments are passed to the start class's static main //启动某个java类的main函数. invokeStaticMain(args.startClass, args.startArgs, classLoader); } 可以看到就是调用了invokeStaticMain传入相应的参数. private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { 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 }); // 函数最后并没有直接调用这个静态成员函数main } 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. */ //抛出一个异常ZygoteInit.MethodAndArgsCaller, throw new ZygoteInit.MethodAndArgsCaller(m, argv); } 可以看此处的设计是直接抛出异常 ZygoteInit.MethodAndArgsCaller(m, argv).最终这个异常一层层返回到 ZygoteInit.main函数.然后才去调用的android.app.ActivityThread类的main函数。看前面我们的ZygoteInit的main 函数,捕获到异常以后调用caller.run()。也就是MethodAndArgsCaller的run.把"main"传过去. public static class MethodAndArgsCaller extends Exception 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() { try { //这样,android.app.ActivityThread类的main函数就被执行了 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { ...... } } } 这样知道此处才调用了对应类的main函数.关于ActivityThread的main函数我们单独分析过,启动了一个looper 循环然后初始化了一些变量,最后初始化了ProcessRecord的thread变量.此时自己成的pid还未设置什么时候设置的 那?想先跟前面你通过native方法fork进程的时候我们还有一条分支没有分析,那就是父类的那一条分支.我们处理 一下.再回到zygote进程中的ZygoteConnection类的runOnce()进入到创建完毕的父类分支.执行handleParentProc() handleParentProc(pid, descriptors, serverPipeFd, parsedArgs)此时参数中的pid就是子类进程的pid. private boolean handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) { if (pid > 0) { setChildPgid(pid); } ...... boolean usingWrapper = false; ...... try { mSocketOutStream.writeInt(pid);//注意 mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error writing to command socket", ex); return true; } return false; } 可以看到最终又往socket的输出流中写入pid.让客户端那边可以读取.然后阻碍AMS的进程中Process.java文件 中zygoteSendArgsAndGetResult的类里面读取socket流里面的东西 ProcessStartResult result = new ProcessStartResult(); result.pid = inputStream.readInt(); android.util.Log.d("zy_pro","Process result.pid = "+result.pid); if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } result.usingWrapper = inputStream.readBoolean(); android.util.Log.d("zy_pro","Process result.usingWrapper = "+result.usingWrapper); return result; 然后一层层返回到AMS的startProcessLocked当中继续Process.ProcessStartResult startResult = Process. start(......) 往下执行.最终通过app.setPid(startResult.pid)来设置pid.这样就完成了基本的进程启动的功能.