前一篇https://www.aiwalls.com/kf/201203/123061.html 文章介紹瞭init進程的啟動過程,其中就有解析init.rc腳本,而根據其內容配置啟動瞭很多重要的服務:Servicemanager和zygote進程就奠定瞭Android的基礎,建立瞭真正的android空間。
進程名稱 進程路徑
zygote /system/bin/app_process
servicemanager /system/bin/servicemanager
bootanim /system/bin/bootanimation
media /system/bin/mediaserver
…
這裡還都是在native世界中,此層分析哪個service沒有啟動,則找到相關的進程加打印即可,比較好分析,成功啟動的進程利用ps命令即可查看。
說明一下android中的兩個不同世界:
JAVA世界:運行基於 dalvik 虛擬機的 JAVA 程序
NATIVE世界:利用 C或C++開發的程序組成native世界。
下面開始分析 zygote 啟動流程:
代碼路徑:frameworks\base\cmds\app_process
啟動參數:
service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
int main(int argc, const char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
// Next arg is startup classname or "–zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("–zygote", arg)) { // init.rc 中的參數值
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "–start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote"); // 利用prctl修改進程名稱
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer); // 這就是真正的重點!!!!
}
….
}
下面開始建立 AndroidRuntime :
路徑:frameworks\base\core\jni
class AppRuntime : public AndroidRuntime
AppRuntime 重載實現瞭 onStarted() , onZygoteInit(), onExit() 函數
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
–> 調用
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
// 基本上再次看到這句話,說明系統重啟瞭
LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
// 1、啟動 虛擬機
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
// 2、註冊 jni 函數
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
3、從 com.android.internal.os.ZygoteInit 類中找到main函數,即調用
ZygoteInit.java類中的main, 此時將進入到 java 世界。。。。
*/
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
歡迎來到 JAVA 世界。。。。。
下面直接分析 ZygoteInit 類中的 main 函數:
路徑: frameworks\base\core\java\com\android\internal\os
public static void main(String argv[]) {
//1 、建立端口號為 50 的監聽套接字,用於接收
// ActivityManangerService 的請求,Fork應用程序
registerZygoteSocket();
// 2、預加載類和資源,優化代碼時這裡可以想點辦法,不過有點麻煩
preloadClasses();
// 3、垃圾回收
gc();
// 4、啟動 SystemServer ,這個下面再重點講解
startSystemServer();
// 5、處理客戶連接與請求,具體由 ZygoteConnection.runOnce()處理
runSelectLoopMode();
…
}
SystemServer 的分析:
這個進程是由 zygote 產生的第一個進程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
{
…
/* Hardcoded command line to start the system server */
String args[] = {
"–setuid=1000",
"–setgid=1000", "–setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
"–capabilities=130104352,130104352",
"–runtime-init",
"–nice-name=system_server", // process name
"com.android.server.SystemServer", // class name
};
// 解析參數
parsedArgs = new ZygoteConnection.Arguments(args);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs); // 後面講述
}
}
–>
forkSystemServer 這是一個jni 函數,調用:
\dalvik\vm\native\dalvik_system_Zygote.c 下面
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
// 根據參數fork 出一個子進程,若成功調用一次則返回兩個值,子進程返回0,父進程返回子進程ID;否則,出錯返回-1
pid = forkAndSpecializeCommon(args);
if(pid > 0) {
gDvm.systemServerPid = pid;
/* There is a slight window that the system server process has crashed
* but it went unnoticed because we haven't published its pid yet. So
* we recheck here just to make sure that all is well.
*/
if (waitpid(pid, &status, WNOHANG) == pid) {
LOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
/*
這裡表示SystemServer進程退出,而其父進程是Zygote,所以這裡 kill掉的就是Zygote進程,即兩者都退出瞭。。。。
*/
}
}
Zygote 與 SystemServer 關系非常緊密,這裡有個小處理邏輯:
static pid_t forkAndSpecializeCommon(const u4* args)
{
setSignalHandler();
}
–>
static void setSignalHandler()
{
int err;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler; // 在此安裝瞭一個信號處理函數
err = sigaction (SIGCHLD, &sa, NULL);
…
}
信號處理函數:
/*
* This signal handler is for zygote mode, since the zygote
* must reap its children
*/
static void sigchldHandler(int s)
{
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/*
* If the just-crashed process is the system_server, bring down zygote
* so that it is restarted by init and system server will be restarted
* from there.
*/
if (pid == gDvm.systemServerPid) {
LOG(LOG_INFO, ZYGOTE_LOG_TAG,
"Exit zygote because system server (%d) has terminated\n",
(int) pid);
kill(getpid(), SIGKILL);
}
}
…
}
Zygote 啟動流程內容太多,下一篇從handleSystemServerProcess 處理流程講解
摘自 andyhuabing的專欄