1 啟動SytemServer 2 孵化應(yīng)用進(jìn)程
一般進(jìn)程啟動,會首先做一些準(zhǔn)備工作,然后進(jìn)進(jìn)入一個Looper循環(huán),來不停的接收消息,消息來源1 可能是通過socket 發(fā)過來的2 有可能是MessageQueue里面的消息3 有可能是Binder 驅(qū)動發(fā)送過來的消息
Zygote 進(jìn)程,系統(tǒng)服務(wù)進(jìn)程,app 進(jìn)程都是如此.
zygote進(jìn)程如何啟動的?
通過init進(jìn)程(Linux啟動之后,用戶空間的第一個進(jìn)程),init進(jìn)程啟動之后,會加載啟動配置文件init.rc,看一下init.rc里面定義了哪些系統(tǒng)服務(wù)需要啟動,Zygote就是要啟動的服務(wù)之一,還包括sm進(jìn)程等,init進(jìn)程通過fork+execve系統(tǒng)調(diào)用啟動了Zygote進(jìn)程
service?zygote?/system/bin/app_process64?-Xzygote /system/bin --zygote --start-system-server// 可以看到service name 是zygote ,通過APP_process 程序啟動,后面為參數(shù)
? ? class main
? ? priority -20
? ? user root
? ? group root readproc
?socket?zygote stream?660?root?system
onrestart?write?/sys/android_power/request_state wake
onrestart?write?/sys/power/state?on
? ? onrestart restart audioserver
? ? onrestart restart cameraserver
? ? onrestart restart media
? ? onrestart restart netd
? ? onrestart restart wificond
? ? writepid /dev/cpuset/smart-system/tasks
? ? onrestart restart surfaceflinger
啟動進(jìn)程
fork函數(shù)
#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);
這個函數(shù)雖然執(zhí)行一次,但是會返回2次的不同的值。就是在這里一個進(jìn)程會變?yōu)閮蓚€進(jìn)程,原本的進(jìn)程叫做父進(jìn)程,新的進(jìn)程叫子進(jìn)程。父進(jìn)程中返回的值為子進(jìn)程的ID號。而子進(jìn)程中返回的是0.
execve函數(shù)
#include<unistd.h>
int?execve(const?char?*file,?const?char?*argv[]?const?char?*envp[]);
參數(shù)1:要執(zhí)行的文件
參數(shù)2:執(zhí)行文件后面跟著的參數(shù),可以是NULL;
參數(shù)3:環(huán)境變量
Fork + handle
pid_t?pid;
? ? ? ? pid = fork();
?if(pid >?0) ?{
// parent process ? ? ? ? ? ??
}?else?if(pid ==?0) {
// child process
? ? ? ? }
?return?0;
Fork + execve
pid_t?pid;
? ? ? ? pid = fork();
?if(pid >?0) ?{
// parent process ? ? ? ? ? ??
}?else?if(pid ==?0) {
// child process
execve(patch,argv,env)
? ? ? ? }
?return?0;
默認(rèn)情況 下創(chuàng)建的子進(jìn)程,繼承了父進(jìn)程的所有資源,如果調(diào)用了execve 加載頂一個二進(jìn)制程序的話,繼承的父進(jìn)程的資源會被清除掉.
SIGCHLD 信號處理
Fork 子進(jìn)程時,父進(jìn)程需要關(guān)注這個信號,父進(jìn)程fork子進(jìn)程,如果子進(jìn)程掛了,那么父進(jìn)程會收到SIGCHLD信號,例如init進(jìn)程fork Zygote進(jìn)程,如果Zygote進(jìn)程掛了,init進(jìn)程就會收到信號,去重啟Zygote進(jìn)程
啟動之后
Zygote進(jìn)程啟動之后做了什么工作?
Zygote進(jìn)程入口是在app_main.cpp main函數(shù)執(zhí)行的,天生是Native的,在Native層做了三件事情:
1 啟動Android虛擬機(jī)
2 注冊Android的JNI函數(shù)
3 進(jìn)入Java世界
看一下app_main.cpp 的main函數(shù),入口函數(shù)
int?main(int?argc,?char*?const?argv[]){
.....
if?(zygote) {
? ? runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}?else?if?(className) {
? ? runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}?
.....
看一下AndroidRuntime::start// ?AndroidRuntime.cpp
void?AndroidRuntime::start(const?char* className,?const?Vector& options,?boolzygote)
{
...
?if?(startVm(&mJavaVM, &env, zygote) !=?0) {
?return;
? ? }
? ? onVmCreated(env);
?/*
? ? ?* Register android functions.
? ? ?*/
?if?(startReg(env) <?0) {
? ? ? ? ALOGE("Unable to register all android natives\n");
?return;
? ? }
...
}
看一下startVm 方法
int?AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv,?bool?zygote)
{
.....
if?(JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) <?0) {//調(diào)用JNI_CreateJavaVM 創(chuàng)建虛擬機(jī), javaVM 是在Zygote進(jìn)程中創(chuàng)建好了,app進(jìn)程是通過Zygote進(jìn)程孵化出來了,所有就有javaVM了
? ? ALOGE("JNI_CreateJavaVM failed\n");
?return?-1;
}
Zygote的Java世界
1 預(yù)加載資源,為了將來孵化子進(jìn)程時可以繼承給他們(常用類,主題,共享庫等資源)
2 啟動SytemServer進(jìn)程
3 進(jìn)入Loop循環(huán),等到socket消息
當(dāng)有新消息時會執(zhí)行processOneCommand,主要干了三件事情:
1 讀取參數(shù)列表readArgumentList,參數(shù)列表是AMS 跨進(jìn)程發(fā)過來的
2 根據(jù)參數(shù)fork子進(jìn)程forkAndSpecialize
3 在子進(jìn)程中開始干活handleChildProc
Runnable processOneCommand(ZygoteServer zygoteServer) {
? ? String args[];
Arguments parsedArgs =?null;
? ? FileDescriptor[] descriptors;
?try?{
args =?readArgumentList();
descriptors =?mSocket.getAncillaryFileDescriptors();
? ....
? ? pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
? ? ? ? ? ? parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
? ? ? ? ? ? parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
? ? ? ? ? ? parsedArgs.appDataDir);
?try?{
?if?(pid ==?0) {
?// in child
?zygoteServer.setForkChild();
? ? ? ? ? ? zygoteServer.closeServerSocket();
? ? ? ? ? ? IoUtils.closeQuietly(serverPipeFd);
serverPipeFd =?null;
?return?handleChildProc(parsedArgs, descriptors, childPipeFd);
// 主要是加載ActivityThread 并調(diào)用main函數(shù)
}?else?{
?// In the parent. A pid < 0 indicates a failure and will be handled in
?// handleParentProc.
?IoUtils.closeQuietly(childPipeFd);
childPipeFd =?null;
? ? ? ? ? ? handleParentProc(pid, descriptors, serverPipeFd);// 把應(yīng)用進(jìn)程pid 通過socket 返回給AMS
?return?null;
? ? ? ? }
}?finally?{
? ? ? ? IoUtils.closeQuietly(childPipeFd);
? ? ? ? IoUtils.closeQuietly(serverPipeFd);
? ? }
}
Zygote fork時要單線程.
除了Zygote進(jìn)程,系統(tǒng)啟動是還是啟動其他重要進(jìn)程
servicemanager.rc
service servicemanager /system/bin/servicemanager
? ? class core animation
user?system
group?system?readproc
? ? critical
? ? onrestart restart healthd
? ? onrestart restart zygote
? ? onrestart restart audioserver
? ? onrestart restart media
? ? onrestart restart surfaceflinger
? ? onrestart restart inputflinger
? ? onrestart restart drm
? ? onrestart restart cameraserver
? ? onrestart restart keystore
? ? onrestart restart gatekeeperd
? ? writepid /dev/cpuset/system-background/tasks
?shutdown?critical
surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
? ? class core animation
user?system
? ? group graphics drmrpc readproc
? ? onrestart restart zygote
? ? writepid /dev/stune/foreground/tasks
?socket?pdx/system/vr/display/client ? ? stream?0666?system?graphics u:object_r:pdx_display_client_endpoint_socket:s0
?socket?pdx/system/vr/display/manager ? ?stream?0666?system?graphics u:object_r:pdx_display_manager_endpoint_socket:s0
?socket?pdx/system/vr/display/vsync ? ? ?stream?0666?system?graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
mediaserver.rc
service media /system/bin/mediaserver
?class?main
? ? user media
? ? group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
ioprio rt?4
? ? writepid /dev/cpuset/smart-system/tasks /dev/stune/foreground/tasks
........