本系列主要介紹Android系統啓動過程當中涉及到的init、Zygote、SystemServer和Launcher。 文本分析的源碼時基於Android8.0源碼。java
Zygote(孵化器),系統中DVM、ART、應用程序進程和SystemServer進程都是由Zygote建立,其中SystemServer是應用層開發常常碰到的,由於應用層APP的進程是經過SystemServer進程建立出來的。android
在Android 8.0系統啓動流程_init(一)中講解到了init啓動Zygote的過程,init.cpp經過解析init.rc中配置信息,該過程稱之爲Zygote的啓動腳本,其流程包括以下:數組
import /init.${ro.zygote}.rc
複製代碼
\system\core\rootdir\init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
....
writepid /dev/cpuset/foreground/tasks
複製代碼
\system\core\rootdir\init.zygote32_64.rc
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
.....
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
複製代碼
以上是init.zygote32.rc、init.zygote32_64.rc的部分源碼,其餘兩種init.zygote64.rc和init.zygote64_32.rc基本相似,腳本文件主要解析以下:bash
在Android 8.0系統啓動流程_init(一)中第四部分講到init啓動Zygote的流程知道最終調用到frameworks\base\cmds\app_process\app_main.cpp下的main方法,以下所示:app
frameworks\base\cmds\app_process\app_main.cpp
int main(int argc, char* const argv[])
{
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;//若是當前運行Zygote進程中,則變量zygote設置爲true
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;//若是當前運行SystemServer進程中,則變量startSystemServer 設置爲true
} else if (strcmp(arg, "--application") == 0) {
application = true;//當前爲應用的進程,則變量 application設置爲true
}
..
}
if (zygote) {//若是運行在Zygote中,則啓動該進程
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
複製代碼
源碼分析以下:socket
Everything up to '--' or first non '-' arg goes to the vm. ... // --zygote : Start in zygote mode // --start-system-server : Start the system server. // --application : Start in application (stand alone, non zygote) mode. // --nice-name : The nice name for this process.ide
經過判斷arg中是否包含「--zygote」、「--start-system-server」、「--application」或其餘參數,來判斷當前運行的是那種進程。函數
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
複製代碼
\frameworks\base\core\jni\AndroidRuntime.cpp
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
...
/* 1 start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/** 2 Register android functions.*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
}
...
//3 獲取類名信息
classNameStr = env->NewStringUTF(className);
...
//4 className的「.」轉爲「/」
char* slashClassName = toSlashClassName(className != NULL ? className : "");
//5 找到ZygoteInit
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
//6.找到ZygoteInit的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//7. 經過JNI調用ZygoteInit的main方法,因爲當前是在Native中,ZygoteInit是java編寫。
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
複製代碼
源碼分析:oop
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
...
//1.新建一個ZygoteServer對象
ZygoteServer zygoteServer = new ZygoteServer();
...
//2.建立一個server端的socket,且名稱爲zygote
zygoteServer.registerServerSocket(socketName);
//3.預加載類和資源
preload(bootTimingsTraceLog);
...
//4.啓動SystemServer進程
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
//5.等待AMS請求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
}
...
複製代碼
ZygoteInit的main方法主要作了以下幾件事: 一、建立一個name爲「zygote」的Socket服務端,用於等待AMS的請求Zygote來建立新的進程; 二、預加載類和資源,包括drawable、color、OpenGL和文本鏈接符資源等,保存到Resources一個全局靜態變量中,下次讀取系統資源的時候優先從靜態變量中查找; 三、啓動SystemServer進程; 四、經過runSelectLoop()方法,等待AMS的請求建立新的應用程序進程。源碼分析
1.registerServerSocket
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
//1.拼接Socket的名稱
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
//2.獲得Soket的環境變量值:ANDROID_SOCKET_zygote
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
//3.經過fileDesc建立文件描述符:fd
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
//4.建立服務端的Socket
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
複製代碼
2.預加載類和資源
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
...
//1.預加載位於/system/etc/preloaded-classes文件中的類
preloadClasses();
...
2.預加載drawble和color的資源信息
preloadResources();
...
//3.經過JNI調用,預加載底層相關的資源
nativePreloadAppProcessHALs();
...
//4.預加載OpenGL資源
preloadOpenGL();
...
//5.預加載共享庫:"android","compiler_rt","jnigraphics"
preloadSharedLibraries();
//6.預加載文本鏈接符資源
preloadTextResources();
...
//7.zygote中,內存共享進程
warmUpJcaProviders();
...
}
複製代碼
3.啓動SystemServer進程
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
//1.建立數組,保存啓動SystemServer的參數
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
//2.建立SystemServer進程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
//3.若是pid爲0,表示運行在新的子進程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//4.處理SystemServer進程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
複製代碼
4.runSelectLoop()
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
/**
* Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's
* worth at a time.
* 運行在Zygote進程中,等待新的鏈接,並讀取請求數據
*/
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//1.將ServerSocket添加到集合中
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
2.開啓死循環,不斷的等待AMS的請求
while (true) {
//3.經過遍歷fds存儲信息,添加至 pollFds數組中
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
//4. 經過遍歷pollFds信息
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
//5.若是pid爲0,代表已經鏈接socket,
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
}else{
/6.若是不等於0 ,AMS向Zyogte進程建立一個新的進程的請求
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
}
...
}
複製代碼