在这张简图中能够看到,从Launcher点击图标启动进程涉及到了3个角色。 其中Launcher是发起请求进程(caller),AMS接收到Launcher的请求并处理,若是要启动的Activity的进程不存在,则经过本地套接字链接到Zygote,向Zygote发起建立进程的请求。Zygote接收该请求并fork出app进程。java
整个过程涉及到的细节比较多,咱们这里只关注核心部分,分红几个小节来讲。linux
Zygote是android系统中的一个重要的守护进程,它的主要做用是:
① 建立VM实例、预加载类和资源等。
② 启动systemserver。
③ 建立本地套接字,等待AMS的fork请求,完成app进程的建立工做。android
下面咱们简单看下它的源码:数据结构
// frameworks/base/cmds/app_process/app_main.cpp int main(int argc, const char* const argv[]) { AppRuntime runtime; ... if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : ""); } ... }
AppRuntime的start()函数继承自基类AndroidRuntime,即上述代码将跳到app
// frameworks/base/core/jni/AndroidRuntime.cpp void AndroidRuntime::start(const char* className, const char* options) { ... JNIEnv* env; // 启动虚拟机 if (startVm(&mJavaVM, &env) != 0) { return; } // 注册android须要的jni函数 if (startReg(env) < 0) { LOGE("Unable to register all android natives\n"); return; } ... // className是com.android.internal.os.ZygoteInit char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); } else { // 调用ZygoteInit的main(String[])方法 env->CallStaticVoidMethod(startClass, startMeth, strArray); } } free(slashClassName); ... }
好了,到这一步,虚拟机已经启动起来了,开始加载并运行主类(ZygoteInit)的main()函数了。socket
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java public static void main(String argv[]) { try { // 建立本地套接字 registerZygoteSocket(); // 预加载类和资源等 preload(); ... if (argv[1].equals("start-system-server")) { // 启动system server进程 startSystemServer(); } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } ... // 建立一个本地套接字,等待客户端的请求 runSelectLoopMode(); closeServerSocket(); } catch (MethodAndArgsCaller caller) { // fork()出来的子进程最终会走到这 // 在这个里面经过反射调用对应主类(即ActivityThread)的main()方法 caller.run(); } catch (RuntimeException ex) { closeServerSocket(); throw ex; } }
private static void runSelectLoopMode() throws MethodAndArgsCaller { // fds--peers 每一项是一一对应的,即<文件描述符,已创建的链接>构成一个二元组 ArrayList<FileDescriptor> fds = new ArrayList(); ArrayList<ZygoteConnection> peers = new ArrayList(); FileDescriptor[] fdArray = new FileDescriptor[4]; // 第一个二元组是<socket监听描述符,null> fds.add(sServerSocket.getFileDescriptor()); peers.add(null); while (true) { ... try { fdArray = fds.toArray(fdArray); // native方法,使用了select io多路复用机制 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) { // index为0的是socket监听描述符,selectReadable()返回0表示来了个新链接 ZygoteConnection newPeer = acceptCommandPeer(); // 将创建好的新链接的二元组添加到集合中 peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { // index>0表示已链接描述符有收到数据了 boolean done; // 让对应的链接来处理数据 done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } } } }
到这一步,Zygote的大致启动流程咱们已经分析完了。关于Zygote如何建立app进程,咱们放到后面AMS那块再说。函数
ActivityManagerService,简称AMS。见名知意,它是用来管理Activity的系统服务。就像linux内核使用task_struct来管理进程同样,AMS要管理Activity,它确定须要用某种数据结构来记录当前系统上Activity的信息。oop
记录每一个Activity的运行时信息
final class ActivityRecord extends IApplicationToken.Stub { final ActivityManagerService service; // 从AndroidManifest.xml解析出来的关于Activity的信息 final ActivityInfo info; // 触发生成这个ActivityRecord的Intent final Intent intent; // 当前activity所属的任务栈 TaskRecord task; // 当前Activity所属进程的信息 ProcessRecord app; ... }
记录当前正在运行的某个进程的完整信息
class ProcessRecord { // 进程名和进程id final String processName; int pid; // AMS经过该Binder接口向app进程发请求 IApplicationThread thread; ... }
Launcher向AMS发起startActivity请求后,AMS会作一系列处理,这里咱们只关心下面2个要点:
① AMS会建立一个ActivityRecord对象来记录该Activity的信息。
② 若是进程不存在,即对应的ProcessRecord对象不存在,则建立ProcessRecord来记录要新建的进程的信息,并向Zygote请求建立新进程。进程建立成功后,在ProcessRecord中记录下Zygote返回新进程的pid。ui
// frameworks/base/services/java/com/android/server/am/ActivityStack.java final int startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, boolean onlyIfNeeded, boolean componentSpecified, ActivityRecord[] outActivity) { ... // 建立即将要启动的Activity的相关信息,并保存在r变量中 ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified); ... }
// frameworks/base/services/java/com/android/server/am/ActivityStack.java private final void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // AMS维护了一个ProcessMap<ProcessRecord> mProcessNames,用来记录经过AMS启动并运行的app进程 // 在这个map里没查到说明该app进程不存在 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid); ... if (app != null && app.thread != null) { // 应用进程存在,则启动对应的Activity try { app.addPackage(r.info.packageName); realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } } // 应用进程不存在,先建立进程 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false); }
// frameworks/base/services/java/com/android/server/am/ActivityManagerService.java final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting) { ... if (app == null) { // 建立一个ProcessRecord,用来记录要启动的进程的信息 app = newProcessRecordLocked(null, info, processName); // 将ProcessRecord存入map中 mProcessNames.put(processName, info.uid, app); } ... startProcessLocked(app, hostingType, hostingNameStr); ... } private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { // 使用Process.start来启动新进程 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, app.info.targetSdkVersion, null); ... app.pid = startResult.pid; // 记录新进程的pid ... }
刚才上面咱们没有看到有关和Zygote socket相关的内容。这块实际上是由ZygoteProcess类实现的。Process.start()通过几层调用,来到ZygoteProcess.startViaZygote()`。this
Process.start() --> ZygoteProcess.start() --> ZygoteProcess.startViaZygote()
private Process.ProcessStartResult startViaZygote(...) { ... // 省略参数的组装过程 synchronized(mLock) { return zygoteSendArgsAndGetResult( openZygoteSocketIfNeeded(abi), // 创建socket链接 argsForZygote); // argsForZygote是要发给Zygote的参数,ArrayList类型 }
private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx { ... // 写入流 final BufferedWriter writer = zygoteState.writer; // 读取流 final DataInputStream inputStream = zygoteState.inputStream; // 按照Zygote协议写数据 // 先写入参数个数,格式:size\n writer.write(Integer.toString(args.size())); writer.newLine(); // 写参数,每一个参数的格式:arg\n 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(); // 读取Zygote返回回来的进程id result.pid = inputStream.readInt(); if (result.pid < 0) { // 若是pid小于0,说明fork失败了 throw new ZygoteStartFailedEx("fork() failed"); } return result; }
ProcessProcess向Zygote发送请求和接收请求的大体流程咱们已经看过了。那Zygote那边怎么接收和处理请求的呢?
// frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { try { // 读取client经过socket发过来的数据 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { Log.w(TAG, "IOException on command socket " + ex.getMessage()); closeSocket(); return true; } ... // 将获取的数据解析成Arguments类型 parsedArgs = new Arguments(args); ... // 建立APP进程 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits); if (pid == 0) { ... // 走子进程的处理逻辑 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); ... } else { ... // 走父进程的处理逻辑 return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } }
此时进程已经建立好了,须要将子进程的pid经过socket传回给AMS了。
// frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java private boolean handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) { ... try { // 将fork出来的进程pid传给AMS mSocketOutStream.writeInt(pid); mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error reading from command socket", ex); return true; } ... }
上面的流程结束后,子进程已经成功建立,接下来子进程将进行自身的初始化,加载主类和执行main(String[])方法。
ZygoteConnection.handleChildProc() --> RuntimeInit.zygoteInit() --> RuntimeInit.zygoteInitNative() --> RuntimeInit.applicationInit() --> RuntimeInit.invokeStaticMain()
private static void invokeStaticMain(String className, String[] argv) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; // 加载主类(android.app.ActivityThread) cl = Class.forName(className); Method m; // 获取main(String[])方法 m = cl.getMethod("main", new Class[] { String[].class }); // 检查main方法是不是public static的 int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException( "Main method is not public and static on " + className); } // 抛出异常,返回到ZygoteInit.main()的catch块中继续执行 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
这段代码的最后将反射获得的Method对象和参数封装成ZygoteInit.MethodAndArgsCaller异常并抛出,这个异常被ZygoteInit的main()方法捕获。
// ZygoteInit.main() catch (MethodAndArgsCaller caller) { // fork()出来的子进程最终会走到这 // 在这个里面经过反射调用对应类的main()方法 caller.run(); } // MethodAndArgsCaller.run() public void run() { try { // 最终经过反射调用main()方法 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { throw new RuntimeException(ex); } }
最终,app进程的ActivityThread类的main()方法开始执行。