安卓源码分析-应用程序进程启动过程
本文基于刘望舒大佬著作《Android进阶解密》结合最新源码整理,丰富而成。内部包含我个人的理解,可能有误
本文基于安卓源码版本9.0.0_r3
Ams发送启动应用程序进程请求
由ActivityManagerService发送启动应用程序进程请求, 在ActivityManagerService类startProcess方法中调用了Process.start,其中传入的uid,和pid在后面有用到
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
4463 private ProcessStartResult startProcess(String hostingType, String entryPoint,
4464 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4465 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4466 long startTime) {
4467 try {
4468 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4469 app.processName);
4470 checkTime(startTime, "startProcess: asking zygote to start proc");
4471 final ProcessStartResult startResult;
4472 if (hostingType.equals("webview_service")) {
4473 startResult = startWebView(entryPoint,
4474 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4475 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4476 app.info.dataDir, null,
4477 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4478 } else {
4479 startResult = Process.start(entryPoint,
4480 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4481 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4482 app.info.dataDir, invokeWith,
4483 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4484 }
4485 checkTime(startTime, "startProcess: returned from zygote!");
4486 return startResult;
4487 } finally {
4488 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4489 }
4490 }
Process.start()内部直接返回zygoteProcess.start() zygoteProcess.start()内部直接返回startViaZygote()方法
/frameworks/base/core/java/android/os/ZygoteProcess.java
357 private Process.ProcessStartResult startViaZygote(final String processClass,
358 final String niceName,
359 final int uid, final int gid,
360 final int[] gids,
361 int runtimeFlags, int mountExternal,
362 int targetSdkVersion,
363 String seInfo,
364 String abi,
365 String instructionSet,
366 String appDataDir,
367 String invokeWith,
368 boolean startChildZygote,
369 String[] extraArgs)
370 throws ZygoteStartFailedEx {
371 ArrayList<String> argsForZygote = new ArrayList<String>();
372
373
374
375 argsForZygote.add("--runtime-args");
376 argsForZygote.add("--setuid=" + uid);
377 argsForZygote.add("--setgid=" + gid);
378 argsForZygote.add("--runtime-flags=" + runtimeFlags);
379 if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
380 argsForZygote.add("--mount-external-default");
381 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
382 argsForZygote.add("--mount-external-read");
383 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
384 argsForZygote.add("--mount-external-write");
385 }
386 argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
387
......
437 synchronized(mLock) {
438 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
439 }
之前传入的UID,PID在这个作为参数添加进argsForZygote 这个list集合中。 方法最后返回zygoteSendArgsAndGetResult方法, 传入值为 openZygoteSocketIfNeeded方法返回的zygotestate和argsForZygote这个list。
/frameworks/base/core/java/android/os/ZygoteProcess.java
280 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
281 ZygoteState zygoteState, ArrayList<String> args)
282 throws ZygoteStartFailedEx {
283 try {
284
285
286 int sz = args.size();
287 for (int i = 0; i < sz; i++) {
288 if (args.get(i).indexOf('\n') >= 0) {
289 throw new ZygoteStartFailedEx("embedded newlines not allowed");
290 }
291 }
292
293
303 final BufferedWriter writer = zygoteState.writer;
304 final DataInputStream inputStream = zygoteState.inputStream;
305
306 writer.write(Integer.toString(args.size()));
307 writer.newLine();
308
309 for (int i = 0; i < sz; i++) {
310 String arg = args.get(i);
311 writer.write(arg);
312 writer.newLine();
313 }
314
315 writer.flush();
316
317
318 Process.ProcessStartResult result = new Process.ProcessStartResult();
319
320
321
322
323 result.pid = inputStream.readInt();
324 result.usingWrapper = inputStream.readBoolean();
325
326 if (result.pid < 0) {
327 throw new ZygoteStartFailedEx("fork() failed");
328 }
329 return result;
330 } catch (IOException ex) {
331 zygoteState.close();
332 throw new ZygoteStartFailedEx(ex);
333 }
334 }
可以看到,zygoteSendArgsAndGetResult把传入的写了启动参数的list写入同样作为传参在之前调用openZygoteSocketIfNeeded方法返回的ZygoteState中,zygotestate是zygoteprocess静态内部类。表示与zygote通讯状态。 回到上面,我们来看看openZygoteSocketIfNeeded的具体执行
563 private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
564 Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
565
566 if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
567 try {
568 primaryZygoteState = ZygoteState.connect(mSocket);
569 } catch (IOException ioe) {
570 throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
571 }
572 maybeSetApiBlacklistExemptions(primaryZygoteState, false);
573 maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
574 }
575 if (primaryZygoteState.matches(abi)) {
576 return primaryZygoteState;
577 }
578
579
580 if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
581 try {
582 secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
583 } catch (IOException ioe) {
584 throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
585 }
586 maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
587 maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
588 }
589
590 if (secondaryZygoteState.matches(abi)) {
591 return secondaryZygoteState;
592 }
593
594 throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
595 }
Android目前支持以下七种ABI:armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips、mips64。主流的ABI包括: armeabiv-v7a: 第7代及以上的 ARM 处理器。 arm64-v8a: 第8代、64位ARM处理器。 armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多。 x86: 平板、模拟器用得比较多。 x86_64: 64位的平板。 mips和mips64很少用,以下不予描述。
zygote进程的main方法会创建名为“zygote”的server端Socket,注释第一处进行连接,第二处判断连接的cpu架构是否和应用程序进程所需的架构匹配,如果不匹配就连接zygote的辅模式。如果辅模式还不匹配。那就抛异常了
Zygote接收请求并创建应用程序进程
zygote连接成功后不管主辅模式都会返回一个zygotestate。在前面的方法zygoteSendArgsAndGetResult里,会把存在list的启动参数写入zygotestate中。这样zygote就收到了创建进程的请求。前面说过,zygote进程的main方法会创建socket等待ams请求。下面看zygote进程main方法。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
779 String socketName = "zygote";
780 String abiList = null;
781 boolean enableLazyPreload = false;
782 for (int i = 1; i < argv.length; i++) {
783 if ("start-system-server".equals(argv[i])) {
784 startSystemServer = true;
785 } else if ("--enable-lazy-preload".equals(argv[i])) {
786 enableLazyPreload = true;
787 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
788 abiList = argv[i].substring(ABI_LIST_ARG.length());
789 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
790 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
791 } else {
792 throw new RuntimeException("Unknown command line argument: " + argv[i]);
793 }
794 }
795
796 if (abiList == null) {
797 throw new RuntimeException("No ABI list supplied.");
798 }
800 zygoteServer.registerServerSocketFromEnv(socketName);
801
802
803 if (!enableLazyPreload) {
804 bootTimingsTraceLog.traceBegin("ZygotePreload");
805 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
806 SystemClock.uptimeMillis());
807 preload(bootTimingsTraceLog);
808 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
809 SystemClock.uptimeMillis());
810 bootTimingsTraceLog.traceEnd();
811 } else {
812 Zygote.resetNicePriority();
813 }
814
815
816 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
817 gcAndFinalize();
818 bootTimingsTraceLog.traceEnd();
819
820 bootTimingsTraceLog.traceEnd();
821
822
823 Trace.setTracingEnabled(false, 0);
824
825 Zygote.nativeSecurityInit();
826
827
828 Zygote.nativeUnmountStorageOnInit();
829
830 ZygoteHooks.stopZygoteNoThreadCreation();
831
832 if (startSystemServer) {
833 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
834
835
836
837 if (r != null) {
838 r.run();
839 return;
840 }
841 }
842
843 Log.i(TAG, "Accepting command socket connections");
844
845
846
847 caller = zygoteServer.runSelectLoop(abiList);
848 } catch (Throwable ex) {
849 Log.e(TAG, "System zygote died with exception", ex);
850 throw ex;
851 } finally {
852 zygoteServer.closeServerSocket();
853 }
854
855
856
857 if (caller != null) {
858 caller.run();
859 }
860 }
zygote的main方法里,后面调用了zygoteServer.runSelectLoop方法 runSelectLoop方法经过层层调用,最后会返回一个Runnable对象,858行调用了其run方法。就是调用了ActivityThread类的main方法,在后面我会详细解释调用过程
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
173 Runnable runSelectLoop(String abiList) {
174 ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
175 ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
176
177 fds.add(mServerSocket.getFileDescriptor());
178 peers.add(null);
179
180 while (true) {
181 StructPollfd[] pollFds = new StructPollfd[fds.size()];
182 for (int i = 0; i < pollFds.length; ++i) {
183 pollFds[i] = new StructPollfd();
184 pollFds[i].fd = fds.get(i);
185 pollFds[i].events = (short) POLLIN;
186 }
187 try {
188 Os.poll(pollFds, -1);
189 } catch (ErrnoException ex) {
190 throw new RuntimeException("poll failed", ex);
191 }
192 for (int i = pollFds.length - 1; i >= 0; --i) {
193 if ((pollFds[i].revents & POLLIN) == 0) {
194 continue;
195 }
196
197 if (i == 0) {
198 ZygoteConnection newPeer = acceptCommandPeer(abiList);
199 peers.add(newPeer);
200 fds.add(newPeer.getFileDesciptor());
201 } else {
202 try {
203 ZygoteConnection connection = peers.get(i);
204 final Runnable command = connection.processOneCommand(this);
205
206 if (mIsForkChild) {
207
208
209 if (command == null) {
210 throw new IllegalStateException("command == null");
211 }
212
213 return command;
214 } else {
215
216 if (command != null) {
.......
zygote等到请求后,会调用204行处processOneCommand方法来创建应用程序进程。processOneCommand是ZygoteConnection类的方法
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
123 Runnable processOneCommand(ZygoteServer zygoteServer) {
124 String args[];
125 Arguments parsedArgs = null;
126 FileDescriptor[] descriptors;
127
128 try {
129 args = readArgumentList();
130 descriptors = mSocket.getAncillaryFileDescriptors();
131 } catch (IOException ex) {
132 throw new IllegalStateException("IOException on command socket", ex);
133 }
134
135
136
137 if (args == null) {
138 isEof = true;
139 return null;
140 }
141
142 int pid = -1;
143 FileDescriptor childPipeFd = null;
144 FileDescriptor serverPipeFd = null;
145
146 parsedArgs = new Arguments(args);
147
......
233
234 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
235 parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
236 parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
237 parsedArgs.instructionSet, parsedArgs.appDataDir);
238
239 try {
240 if (pid == 0) {
241
242 zygoteServer.setForkChild();
243
244 zygoteServer.closeServerSocket();
245 IoUtils.closeQuietly(serverPipeFd);
246 serverPipeFd = null;
247
248 return handleChildProc(parsedArgs, descriptors, childPipeFd,
249 parsedArgs.startChildZygote);
250 } else {
251
252
253 IoUtils.closeQuietly(childPipeFd);
254 childPipeFd = null;
255 handleParentProc(pid, descriptors, serverPipeFd);
256 return null;
257 }
258 } finally {
259 IoUtils.closeQuietly(childPipeFd);
260 IoUtils.closeQuietly(serverPipeFd);
261 }
通过forkAndSpecialize方法来fork一个线程,看fork介绍
fork是UNIX或类UNIX中的分叉函数,fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。
所以在后面判断pid是否等于0,如果等于0说明已经是运行在fork出的新线程里面了。 然后返回handleChildProc执行应用程序进程,handleChildProc方法内部重要的先判断当前进程是不是zygote进程
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
882 if (!isZygote) {
883 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
884 null );
885 } else {
886 return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
887 parsedArgs.remainingArgs, null );
888 }
不是zygote进程是新线程就调用了ZygoteInit类的zygoteInit方法,方法内部重要的有:
- ZygoteInit.nativeZygoteInit();创建了Binder线程池
- RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);调用RuntimeInit的applicationInit方法
applicationInit返回了findStaticMain方法
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
287 protected static Runnable findStaticMain(String className, String[] argv,
288 ClassLoader classLoader) {
289 Class<?> cl;
290
291 try {
292 cl = Class.forName(className, true, classLoader);
293 } catch (ClassNotFoundException ex) {
294 throw new RuntimeException(
295 "Missing class when invoking static main " + className,
296 ex);
297 }
298
299 Method m;
300 try {
301 m = cl.getMethod("main", new Class[] { String[].class });
302 } catch (NoSuchMethodException ex) {
303 throw new RuntimeException(
304 "Missing static main on " + className, ex);
305 } catch (SecurityException ex) {
306 throw new RuntimeException(
307 "Problem getting static main on " + className, ex);
308 }
309
310 int modifiers = m.getModifiers();
311 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
312 throw new RuntimeException(
313 "Main method is not public and static on " + className);
314 }
315
316
322 return new MethodAndArgsCaller(m, argv);
323 }
324
先通过反射获取了classname的类,classname是在之前传入的,值为“android.app.ActivityThread” 然后获取ActivityThread的main方法。最后返回new一个MethodAndArgsCaller 对象, 回到之前zygote等待ams请求创建应用程序进程的地方
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
847 caller = zygoteServer.runSelectLoop(abiList);
848 } catch (Throwable ex) {
849 Log.e(TAG, "System zygote died with exception", ex);
850 throw ex;
851 } finally {
852 zygoteServer.closeServerSocket();
853 }
854
855
856
857 if (caller != null) {
858 caller.run();
859 }
860 }
之前说过runSelectLoop经过层层调用会返回一个Runnable类型对象,层层调用之后返回的就是上面的MethodAndArgsCaller 对象传入caller里,最后给caller做了判空就运行了内部实现的run方法,如下
static class MethodAndArgsCaller implements Runnable {
480
481 private final Method mMethod;
482
483
484 private final String[] mArgs;
485
486 public MethodAndArgsCaller(Method method, String[] args) {
487 mMethod = method;
488 mArgs = args;
489 }
490
491 public void run() {
492 try {
493 mMethod.invoke(null, new Object[] { mArgs });
494 } catch (IllegalAccessException ex) {
495 throw new RuntimeException(ex);
496 } catch (InvocationTargetException ex) {
497 Throwable cause = ex.getCause();
498 if (cause instanceof RuntimeException) {
499 throw (RuntimeException) cause;
500 } else if (cause instanceof Error) {
501 throw (Error) cause;
502 }
503 throw new RuntimeException(ex);
504 }
505 }
506 }
在MethodAndArgsCaller构造方法方法中,把传入的参数给成员变量赋值 内部493行调用了mMethod方法,也就是ActivityThread的main方法。
/frameworks/base/core/java/android/app/ActivityThread.java
6623 public static void main(String[] args) {
6624 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6625
6626
6627
6628
6629 CloseGuard.setEnabled(false);
6630
6631 Environment.initForCurrentUser();
6632
6633
6634 EventLogger.setReporter(new EventLoggingReporter());
6635
6636
6637 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6638 TrustedCertificateStore.setDefaultUserDirectory(configDir);
6639
6640 Process.setArgV0("<pre-initialized>");
6641
6642 Looper.prepareMainLooper();
6643
6644
6645
6646 long startSeq = 0;
6647 if (args != null) {
6648 for (int i = args.length - 1; i >= 0; --i) {
6649 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
6650 startSeq = Long.parseLong(
6651 args[i].substring(PROC_START_SEQ_IDENT.length()));
6652 }
6653 }
6654 }
6655 ActivityThread thread = new ActivityThread();
6656 thread.attach(false, startSeq);
6657
6658 if (sMainThreadHandler == null) {
6659 sMainThreadHandler = thread.getHandler();
6660 }
6661
6662 if (false) {
6663 Looper.myLooper().setMessageLogging(new
6664 LogPrinter(Log.DEBUG, "ActivityThread"));
6665 }
6666
6667
6668 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6669 Looper.loop();
6670
6671 throw new RuntimeException("Main thread loop unexpectedly exited");
6672 }
6673
|