Android 之 zygote 與程式建立
在android中,應用程式的入口是ActivityThead中的main函式,那麼之後系統是怎樣為應用程式建立程式的呢?SystemService又是怎樣建立的?答案是:zygote
zygote翻譯成中文是受精卵的意思,名字比較奇怪、但是很有意思。在android中,大部分的應用程式程式都是由zygote來建立的,為什麼用大部分,因為還有一些程式比如系統引導程式、init程式等不是有zygote建立的。相反,zygote還是在init程式之後才被建立的。在android中提到zygote,主要兩塊,一個是C/C++編寫的zygote,主要用來為應用和SystemService fork程式的。一個是java編寫的zygote介面,負責為應用和service呼叫C/C++ zygote的介面執行fork,從而建立VM程式。說明:在android中,service主要有NativeService和SystemService。SystemService主要是指系統中service,比如,InputMethodService、ActivityManagerService等。
zygote在android中主要有兩個作用:
建立執行時環境並啟動虛擬機器,執行com.android.internal.os.ZygoteInit的main函式,從而fork SystemService- runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
啟動SystemServer:
我們來看看zygote是怎樣建立SystemService程式的。在../base/cmds/app_process/app_main.cpp的主函式中,有這樣一段程式碼,它執行了
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); //runtime繼承自AndroidRuntime
也就是說,在主函式中,初始化了執行時環境,並且建立虛擬機器,然後執行再com.android.internal.os.ZygoteInit的main函式
再來看看com.android.internal.os.ZygoteInit的main中都做了哪些事情。在看ZygoteInit之前,有必要先來看下相關的類,類圖如下:
在ZygoteInit的main函式中,主要執行了:
- registerZygoteSocket();//登記Listen埠
- startSystemServer();//啟動SystemServer
startSystemServer()呼叫Zygote的native方法 forkSystemServer(); 到這裡,java端的Zygote的準備工作就結束了,接下來就交給C/C++端的Zygote來執行fork任務了。來看下程式碼:
在 ../dalvik/vm/native/dalvik_system_Zygote.c 中
- static void Dalvik_dalvik_system_Zygote_forkSystemServer(
- const u4* args, JValue* pResult)
- {
- pid_t pid;
- /*呼叫forkAndSpecializeCommon,執行fork */
- pid = forkAndSpecializeCommon(args, true);
- /* 檢查fork後返回的程式pid */
- if (pid > 0) {
- int status;
- LOGI("System server process %d has been created", pid);
- gDvm.systemServerPid = pid;
- if (waitpid(pid, &status, WNOHANG) == pid) {
- LOGE("System server process %d has died. Restarting Zygote!", pid);
- kill(getpid(), SIGKILL);
- }
- }
- RETURN_INT(pid);
- }
在這個裡面的fork程式主要是使用linux的fork程式。
經過這樣的過程SystemServer程式就建立起來了。android中的所有服務迴圈框架都是建立咋SystemServer上,接下來在SystemServer上,就可以建立所有系統服務。可參看:SystemServer.main();
系統服務啟動後會呼叫ActivityManagerService的systemReady方法,並最終啟動HomeActivity。
啟動應用程式:
我們在上一篇介紹ActivityThread和ActivityManagerService時已經講過,程式的主入口是在ActivityThread的main函式,activity的startActivity最終是在ActivityManagerService中執行的,那麼應用程式的程式是怎麼建立的?看下類圖:
我們再來看看ActivityManagerService中的startProcessLocked方法。
- int pid = Process.start("android.app.ActivityThread",
- mSimpleProcessManagement ? app.processName : null, uid, uid,
- gids, debugFlags, null);
通過Process的start方法來建立程式。
- / **
- *通過Zygote程式來建立新的vm程式
- */
- public static final int start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags,String[] zygoteArgs)
- {
- if (supportsProcesses()) {
- try {
- return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, zygoteArgs); //argsForZygote.add("--runtime-init")初始化執行環境
- } catch (ZygoteStartFailedEx ex) {
- Log.e(LOG_TAG,
- "Starting VM process through Zygote failed");
- throw new RuntimeException(
- "Starting VM process through Zygote failed", ex);
- }
- } else {
- // Running in single-process mode
- Runnable runnable = new Runnable() {
- public void run() {
- Process.invokeStaticMain(processClass);
- }
- };
- // Thread constructors must not be called with null names (see spec).
- if (niceName != null) {
- new Thread(runnable, niceName).start();
- } else {
- new Thread(runnable).start();
- }
- return 0;
- }
- }
在ZygoteConnection中獲取套接字連線,並解析啟動引數。來看下runOnce方法:
從LocalSocket. mSocket中解析引數
- try {
- args = readArgumentList();
- descriptors = mSocket.getAncillaryFileDescriptors();
- } catch (IOException ex) {
- Log.w(TAG, "IOException on command socket " + ex.getMessage());
- closeSocket();
- return true;
- }
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
這樣應用程式的程式就建立起來了。從ActivityManagerService開始的時序圖如下:
總結:
在android中SystemService的啟動是在Zygote程式建立好後進行的,並且由Zygote程式建立好DVM執行環境,載入ZygoteInit的main函式,最終呼叫Zygote的本地方法forkSystemServer,並執行linux的fork方法建立SystemServer程式。應用程式的程式也是由Zygote建立的,在ActivityManagerService中的startProcessLocked中呼叫了Process.start()方法。並通過連線呼叫Zygote的native方法forkAndSpecialize,執行fork任務。應用程式和服務程式位於不同的程式中,他們之間是通過IPC進行資料傳遞的。接下來一篇會介紹在android中的程式間通訊機制:Binder相關文章
- Android之Zygote介紹AndroidGo
- 圖解 Android 系列(二)深入理解 init 與 zygote 程式圖解AndroidGo
- Android系統啟動流程(二)解析Zygote程式AndroidGo
- Android 世界中,誰喊醒了 Zygote ?AndroidGo
- Android系統程式Zygote啟動過程的原始碼分析(3)AndroidGo原始碼
- Android程式框架:程式的建立、啟動與排程流程Android框架
- Android 之 Binder與程式間通訊Android
- zygote啟動流程Go
- [譯]Android系統是如何啟動應用程式的?從Zygote到Activity的onCreate()AndroidGo
- Android系統原始碼分析–Zygote和SystemServer啟動過程Android原始碼GoServer
- Android系統原始碼分析--Zygote和SystemServer啟動過程Android原始碼GoServer
- Android高手進階教程(二十一)之---Android中建立與幾種解析xml的方法!AndroidXML
- wcf 配置與程式碼建立
- ()Android中的Activity建立與週期Android
- [Android]你不知道的Android程式化(2)--建立程式Android
- Zygote家的大兒子 —— SystemServerGoServer
- Android之Window與WindowManagerAndroid
- Android執行緒的建立與銷燬Android執行緒
- [android]android自動化測試二之命令列建立AVDAndroid命令列
- Android的UI顯示原理之Surface的建立AndroidUI
- TCP/IP之TCP的建立與終止TCP
- Android 程式之間通訊Android
- Android框架模式之MVC與MVPAndroid框架模式MVCMVP
- oracle之 手動建立 emp 表 與 dept 表Oracle
- Android開發 - inflate方法與建立檢視解析Android
- Android程式與執行緒Android執行緒
- Android 進階 ———— Handler系列之建立子執行緒HandlerAndroid執行緒
- Android多程式之Binder的使用Android
- Android之串列埠程式設計Android串列埠程式設計
- Android之網路程式設計Android程式設計
- Flutter與android之間的通訊FlutterAndroid
- Android框架之Volley與GlideAndroid框架IDE
- Android 之 Window、WindowManager 與視窗管理Android
- Android 之 ServiceManager與服務管理Android
- Android之ListView與SimpleAdapter的使用AndroidViewAPT
- SQL入門之5 表的建立與修改1SQL
- 程式碼安全之程式碼混淆及加固(Android)?Android
- Android的程式與執行緒Android執行緒