ART
在上文的Android 系統的啓動過程中說到Android
的虛擬機ART(AndroidRuntime)
ART
的主要方法有
- startVM()
啓動虛擬機並且初始化
- startReg()
註冊一些JNI
的方法
- start()
啓動Zygote
,依次執行 startVM()->startReg()->callMain()
- callMain()
通過反射調用傳入的className
對象的main
函數,如在init.cpp
函數裏面傳入的ZygoteInit
對象和RuntimeInit
對象,調用callMain
方法就會調用對應的main
方法。
AppRuntime
的主要方法有
setClassNameAndArgs()
設置傳入的參數onVmCreated()
重載AndroidRuntime
方法,調用了FindClass
方法,不能再onStarted
方法裏面調用,因爲它創建了一個
bootClassLoader
加載器,如果在onStarted
裏面調用,就無法找到改方法了。onStarted
開啓了一個線程池,callMain
調用了主函數onZygoteInit
開啓了一個線程池OnExit
退出對應的線程
Zygote
從上文知道,app_main.cpp
裏面的main
函數通過init.rc
傳入的參數之後來判斷Zygote
是通過Zygote模式來啓動還是通過非Zygote模式來啓動。然後通過AppRuntime
調用AndroidRuntime
的callMain
函數來調用對應的main
函數
- 首先來看
ZygoteInit
的Main
函數
public static void main(String argv[]) {
//...
// android-7.1.2_r36/core/java/com/android/internal/os/ZygoteInit.java
try {
//...
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
}
//...
}
//...
registerZygoteSocket(socketName);
//...
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
ZygoteInit
主要做了下面幾個事情
- registerZygoteSocket()
創建了一個socket
接口,用來和ActivityManagerService
通訊
- startSystemServer()
當傳入參數start-system-server
的時候啓動SystemServer
組件
- runSelectLoop()
執行一個無限循環,在創建的socket
接口上等待ActivityManagerService
請求創建新的應用程序進程
registerZygoteSocket
詳細代碼如下:
//...
// android-7.1.2_r36/core/java/com/android/internal/os/ZygoteInit.java
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
首先獲取fullsocketName
的值,也就是ANDROID_SOCKET_zygote
,然後獲取對應的文件描述符fileDesc
,通過fileDesc
創建了LocalServerSocket
對象,這樣就可以接收到發送給zygote
的消息了。
startSystemServer
詳細代碼如下:
//...
// android-7.1.2_r36/core/java/com/android/internal/os/ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
//...
try {
//...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
根據相應的參數創建了SystemService
進程。當SystemService
進程創建完後,調用handleSystemServerProcess()
方法
// android-7.1.2_r36/core/java/com/android/internal/os/ZygoteInit.java
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
//...
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
//...
}
接下來進入了RuntimeInit.zygoteInit
裏面
// android-7.1.2_r36/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
//...
commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
nativeZygoteInit()
調用AppRuntime.cpp::onZygoteInit()
,後續用於Binder
通信applicationInit()
通過反射調用了SystemService.java
的Main
函數runSelectLoop
詳細代碼如下:
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
//...
while (true) {
//...
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
執行一個死循環監聽消息,通過acceptCommandPeer()
方法可以獲取到客戶端發送過來的消息,通過ZygoteConnection
進行通信,緊接着進入到runOnce()
,進行相應的處理,從而創建出來一個新的進程
RuntimeInit
的Main
函數
//...
// android-7.1.2_r36/core/java/com/android/internal/os/RuntimeInit.java
public static final void main(String[] argv) {
enableDdms();
//...
commonInit();
//...
nativeFinishInit();
if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
}
RuntimeInit
主要做了下面幾個事情
- enableDdms()
開啓DDMS
- commonInit()
設置線程異常的默認處理,系統時間初始化,初始化日誌打印LogManager
- nativeFinishInit()
執行原生代碼
總結
通過上文的描述,最終的流程大概如下