Android設備啓動過程當中,先是Linux內核加載完,接着Android中的第一個進程init啓動,它會啓動一些須要開機啓動的進程。
Zygote就是進程init啓動起來的。Android中全部應用程序進程,以及運行系統關鍵服務的System進程都是由Zygote建立的。它經過複製自身的形式建立其它進程。Zygote在啓動時會在內部建立一個虛擬機實例,所以,經過複製Zygote獲得的其它應用程序進程和System進程均可以快速地在內部得到一個虛擬機地拷貝。Zygote啓動完成後就當即將System進程啓動,以便各類關鍵服務被啓動運行。java
它以服務的形式被啓動。android
進程內建立一個虛擬機實例,並註冊一系列JNI方法。
frameworks/base/core/jni/AndroidRuntime.cppapp
/* start the virtual machine. */ startVM(&mJavaVM, &env); /* Register android functions. */ startReg(env);
接下來執行「com.android.internal.os.ZygoteInit」Java類的main方法繼續執行啓動。socket
package com.android.internal.os; import android.net.LocalServerSocket; ... public class ZygoteInit { private static LocalServerSocket sServerSocket; public static void main(String argv[]) { ... registerZygoteSocket(); ... if (argv[1].equals("true")) { startSystemServer(); } else if (!argv[1].equals("false")) { throw new RuntimeException(argv[0] + USAGE_STRING); } ... if (ZYGOTE_FORK_MODE) { runForkMode(); } else { runSelectLoopMode(); } ... closeServerSocket(); ... } }
Zygote調用registerZygoteSocket();
建立一個LocalServerSocket sServerSocket
的Server端Socket,等待之後運行在System進程中的服務ActivityManagerService建立的Client端Socket鏈接,而後經過Socket進程間通訊通知Zygote建立新的應用程序進程。ide
/** * Prepare the arguments and fork for the system server process. */ private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { /* Hardcoded command line to start the system server */ String args[] = new String[] { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006", "--capabilities=130104352,130104352", "--rlimit=8,", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; ... ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, debugFlags, rlimits, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { handleSystemServerProcess(parsedArgs); } return true; }
變量args保存啓動System進程的參數。
Zygote.forkSystemServer()複製當前進程來建立子進程。
handleSystemServerProcess()繼續處理System進程的啓動。oop
private static void runSelectLoopMode() throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList(); ArrayList<ZygoteConnection> peers = new ArrayList(); FileDescriptor[] fdArray = new FileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor()); peers.add(null); while (true) { ... 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(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { boolean done; done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } } } } /** * Waits for and accepts a single command connection. Throws * RuntimeException on failure. */ private static ZygoteConnection acceptCommandPeer() { try { return new ZygoteConnection(sServerSocket.accept()); } catch (IOException ex) { throw new RuntimeException( "IOException during accept()", ex); } }
無限循環,等待來自AMS建立的Socket鏈接。
sServerSocket在fds[0]位置。
每當accept()返回一個鏈接後,將對應此鏈接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置後),下一次讀取到數據時,若在fds[0]之後的,說明是前面的newPeer鏈接收到的AMS的建立新應用程序進程的請求。
runOnce()用來處理AMS建立新應用程序進程的請求。ui
ZygoteInit.handleSystemServerProcess()執行System進程的啓動操做。.net
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); /* * Pass the remaining arguments to SystemServer. * "--nice-name=system_server com.android.server.SystemServer" */ RuntimeInit.zygoteInit(parsedArgs.remainingArgs); /* should never reach here */ }
Zygote複製自身建立的子進程作爲System進程,這樣它獲得了Zygote的Server Socket,可是用不到,因此第一句closeServerSocket()
關閉此套接字。線程
package com.android.internal.os; public class RuntimeInit { public static final void zygoteInit(String[] argv) throws ZygoteInit.MethodAndArgsCaller { ... commonInit(); zygoteInitNative(); ... // Remaining arguments are passed to the start class's static main String startClass = argv[curArg++]; String[] startArgs = new String[argv.length - curArg]; System.arraycopy(argv, curArg, startArgs, 0, startArgs.length); invokeStaticMain(startClass, startArgs); } }
zygoteInitNative()在System進程中啓動一個Binder線程池。
RuntimeInit.invokeStaticMain()靜態方法調用"com.android.server.SystemServer"
的main方法。debug
傳遞調用native方法init1():
class SystemServer { /** * This method is called from Zygote to initialize the system. This will cause the native * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back * up into init2() to start the Android services. */ native public static void init1(String[] args); }
init1()的工做:
註冊Service Manager的死亡通知:調用binderDied()。System進程執行kill結束本身。
建立SurfaceFlinger、和SensorService兩個服務。
返回SystemServer.init2()繼續啓動java語言開發的系統服務。
public static final void init2() { Thread thr = new ServerThread(); thr.setName("android.server.ServerThread"); thr.start(); }
ServerThread繼承自Thread。
class ServerThread extends Thread { @Override public void run() { Looper.prepare(); ... // Critical services... try { ... Slog.i(TAG, "Activity Manager"); context = ActivityManagerService.main(factoryTest); ... Slog.i(TAG, "Package Manager"); pm = PackageManagerService.main(context, factoryTest != SystemServer.FACTORY_TEST_OFF); ... Slog.i(TAG, "Content Manager"); ContentService.main(context, factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL); ... Slog.i(TAG, "Window Manager"); wm = WindowManagerService.main(context, power, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ... ((ActivityManagerService)ServiceManager.getService("activity")) .setWindowManager(wm); ... } catch (RuntimeException e) { Slog.e("System", "Failure starting core service", e); } ... Looper.loop(); Slog.d(TAG, "System ServerThread is exiting!"); } }
啓動各個Service而後註冊到ServiceManager。
各個服務都使用Binder和其它服務使用者進程進行就行交互。
(本文使用Atom編寫)