上一篇博客介紹了ZygoteService的啟動過程示姿,在Zygote的啟動后首先就會啟動SystemServer栈戳,所以SystemServer可以看做是Zygote嫡長子览露。能夠成為嫡長子的必然有著非常重要的作用荧琼,的確是這樣,Android應(yīng)用框架中的各種Service,例如ActivityManagerService命锄,PacakgeManagerService堰乔,WindowManagerService等等重要的系統(tǒng)服務(wù)都是在SystemServer中啟動的。這篇博客我們就來看看SystemServer的啟動過程脐恩。
1.SystemServer啟動
SystemServer是通過Zygote.startSystemServer來啟動的镐侯,所以首先來看看對應(yīng)的代碼,其對應(yīng)的實現(xiàn)在dalvik_system_Zygote.c中,這是一個native函數(shù):
[-->dalvik_system_Zygote.c]
static voidDalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_tpid;
//根據(jù)參數(shù)驶冒,fork一個子進程
pid =forkAndSpecializeCommon(args);
if (pid > 0) {
int status;
gDvm.systemServerPid = pid;//保存system_server的進程id
//函數(shù)退出前須先檢查剛創(chuàng)建的子進程是否退出了。
if(waitpid(pid, &status, WNOHANG) == pid) {
//如果system_server退出了骗污,Zygote直接干掉了自己
//看來Zygote和SS的關(guān)系異常緊密崇猫,簡直是生死與共!
kill(getpid(), SIGKILL);
}
}
RETURN_INT(pid);
}
通過上面的代碼可以看出需忿,Zygote會fork出一個進程作為SystemServer的宿主诅炉,具體的操作是在forkAndSpecializeCommon
中完成。在完成創(chuàng)建SystemServer的進程之后屋厘,Zygote會檢查其對應(yīng)的進程是否退出涕烧,如果退出了,Zygote也會殺死自己汗洒。
下面议纯,再看看forkAndSpecializeCommon,代碼如下所示:
[-->dalvik_system_Zygote.c]
static pid_t forkAndSpecializeCommon(const u4*args)
{
pid_tpid;
uid_tuid = (uid_t) args[0];
gid_tgid = (gid_t) args[1];
ArrayObject* gids = (ArrayObject *)args[2];
u4debugFlags = args[3];
ArrayObject *rlimits = (ArrayObject *)args[4];
//設(shè)置信號處理溢谤,待會兒要看看這個函數(shù)瞻凤。
setSignalHandler();
pid =fork(); //fork子進程
if (pid== 0) {
//對子進程要根據(jù)傳入的參數(shù)做一些處理,例如設(shè)置進程名溯香,設(shè)置各種id(用戶id鲫构,組id等)
}
......
}
最后看看setSignalHandler函數(shù),它由Zygote在fork子進程前調(diào)用玫坛,代碼如下所示:
[-->dalvik_system_Zygote.c]
static void setSignalHandler()
{
interr;
structsigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler;
err =sigaction (SIGCHLD, &sa, NULL);//設(shè)置信號處理函數(shù)结笨,該信號是子進程死亡的信號
}
直接看這個信號處理函數(shù)sigchldHandler
static void sigchldHandler(int s)
{
pid_tpid;
intstatus;
while((pid = waitpid(-1, &status, WNOHANG)) > 0) {
} else if (WIFSIGNALED(status)) {
}
}
//如果死去的子進程是SS,則Zygote把自己也干掉了湿镀,這樣就做到了生死與共炕吸!
if(pid == gDvm.systemServerPid) {
kill(getpid(), SIGKILL);
}
}
2.SystemServer的作用
接下來看看SystemServer在啟動的過程中具體做了些什么。
pid =Zygote.forkSystemServer();
if(pid == 0) { //子進程處理邏輯:
handleSystemServerProcess(parsedArgs);
}
從代碼中可以看到勉痴,當(dāng)SystemServer被fork出來之后赫模,會調(diào)用handleSystemServerProcess來處理自身的啟動邏輯。
[-->ZygoteInit.java]
private static void handleSystemServerProcess(
ZygoteConnection.ArgumentsparsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
//關(guān)閉從Zygote那里繼承下來的Socket蒸矛。
closeServerSocket();
//設(shè)置SS進程的一些參數(shù)瀑罗。
setCapabilities(parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
//調(diào)用ZygoteInit函數(shù)胸嘴。
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
}
好了,SS走到RuntimeInit了斩祭,它的代碼在RuntimeInit.java中劣像,如下所示:
[-->RuntimeInit.java]
public static final void zygoteInit(String[]argv)
throws ZygoteInit.MethodAndArgsCaller {
//做一些常規(guī)初始化
commonInit();
//①native層的初始化。
zygoteInitNative();
intcurArg = 0;
for (/* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
//設(shè)置進程名為niceName摧玫,也就是"system_server"
Process.setArgV0(niceName);
}
}
//startClass名為"com.android.server.SystemServer"
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
//②調(diào)用startClass耳奕,也就是com.android.server.SystemServer類的main函數(shù)。
invokeStaticMain(startClass, startArgs);
}
上面的代碼有兩個地方比較重要:
- zygoteInitNative诬像,執(zhí)行native層的初始化
- invokeStaticMain(startClass, startArgs):執(zhí)行SystemServer的main函數(shù)屋群。
接下來分別講一下以上兩點:
2.1 zygoteInitNative
該函數(shù)最終會調(diào)用AppMain的onZygoteInit函數(shù):
[-->App_main.cpp]
virtual void onZygoteInit()
{
//下面這些東西和Binder有關(guān)系
sp<ProcessState> proc = ProcessState::self();
if(proc->supportsProcesses()) {
proc->startThreadPool();//啟動一個線程,用于Binder通信坏挠。
}
}
2.2 invokeStaticMain
[-->RuntimeInit.java]
private static void invokeStaticMain(StringclassName, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
......
//className為"com.android.server.SystemServer"
Class<?> cl;
try {
cl = Class.forName(className);
}catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class wheninvoking static main " + className,
ex);
}
Method m;
try {
//找到com.android.server.SystemServer類的main函數(shù)芍躏,肯定有地方要調(diào)用它
m = cl.getMethod("main", new Class[] { String[].class });
}catch (NoSuchMethodException ex) {
......
}catch (SecurityException ex) {
......
}
int modifiers = m.getModifiers();
if(! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
......
}
//拋出一個異常
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
這個函數(shù)比較奇怪的一點是,在加載到com.android.server.SystemServer
類以及找到其對應(yīng)的main函數(shù)之后癞揉,并沒有直接啟動該函數(shù)纸肉,而是拋出了一個異常溺欧,這個異常會在ZygoteInit的main函數(shù)中catch喊熟,然后才啟動對應(yīng)的面函數(shù)。這樣做的原因是為了清空堆棧姐刁,讓用戶看到堆棧的棧頂是ZygoteInit.main芥牌。
接下來再來看看Zygote在啟動后都干了些什么,首先來看看main函數(shù):
[-->SystemServer.java]
public static void main(String[] args) {
......
//加載libandroid_servers.so
System.loadLibrary("android_servers");
//調(diào)用native的init1函數(shù)聂使。
init1(args);
}
所以啟動過程轉(zhuǎn)移到了init1函數(shù)中:
init1是native函數(shù)壁拉,在com_android_server_SystemServer.cpp中實現(xiàn):
[-->com_android_server_SystemServer.cpp]
extern "C" int system_init();
static voidandroid_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();//調(diào)用另外一個函數(shù)。
}
system_init的實現(xiàn)在system_init.cpp中柏靶,它的代碼如下所示:
[-->system_init.cpp]
extern "C" status_t system_init()
{
//下面這些調(diào)用和Binder有關(guān)弃理,我們會在第6章中講述,這里先不必管它屎蜓。
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
sp<GrimReaper>grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
charpropBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf,"1");
if(strcmp(propBuf, "1") == 0) {
//SurfaceFlinger服務(wù)在system_server進程創(chuàng)建
SurfaceFlinger::instantiate();
}
......
//調(diào)用com.android.server.SystemServer類的init2函數(shù)
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
runtime->callStatic("com/android/server/SystemServer","init2");
//下面這幾個函數(shù)調(diào)用和Binder通信有關(guān)痘昌。
if (proc->supportsProcesses()) {
ProcessState::self()->startThreadPool();
//調(diào)用joinThreadPool后,當(dāng)前線程也加入到Binder通信的大潮中
IPCThreadState::self()->joinThreadPool();
}
returnNO_ERROR;
}
init1函數(shù)創(chuàng)建了一些系統(tǒng)服務(wù)炬转,然后把調(diào)用線程加入Binder通信中辆苔。不過其間還通過JNI調(diào)用了com.android.server.SystemServer類的init2函數(shù),下面就來看看這個init2函數(shù)扼劈。init2在Java層驻啤,代碼在SystemServer.java中:
[-->SystemServer.java]
public static final void init2() {
Threadthr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();//啟動一個ServerThread
}
啟動了一個ServerThread線程。請直接看它的run函數(shù)荐吵。這個函數(shù)比較長骑冗,大概看看它干了什么即可赊瞬。
[-->SystemServer.java::ServerThread的run函數(shù)]
public void run(){
....
//啟動Entropy Service
ServiceManager.addService("entropy",new EntropyService());
//啟動電源管理服務(wù)
power =new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
//啟動電池管理服務(wù)。
battery= new BatteryService(context);
ServiceManager.addService("battery", battery);
//初始化看門狗
Watchdog.getInstance().init(context,battery, power, alarm,
ActivityManagerService.self());
//啟動WindowManager服務(wù)
wm =WindowManagerService.main(context, power,
factoryTest !=SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE,wm);
//啟動ActivityManager服務(wù)
(ActivityManagerService)ServiceManager.getService("activity")).setWindowManager(wm);
......//系統(tǒng)各種重要服務(wù)都在這里啟動
Looper.loop(); //進行消息循環(huán)贼涩,然后處理消息森逮。關(guān)于這部分內(nèi)容參見第5章。
}
init2函數(shù)比較簡單磁携,就是單獨創(chuàng)建一個線程褒侧,用以啟動系統(tǒng)各項服務(wù)。至此谊迄,SystemServer啟動完畢闷供。