[轉載]Android系統運行機制

發現一篇博文中的圖片很好看,貼在此:

Android系統剖析 和 Android系統的運行機制,mattermon,2015-02-28

Android源碼學習之八—系統啓動過程,2010-12-31

深入理解 Android 卷II, 極客學院在線閱讀

深入Android frameworks, 極客學院技術筆記

Android的啓動過程可以分爲兩個階段,第一階段是Linux的啓動,第二階段纔是Android的啓動,下面我們分別來了解一下具體的過程。

首先是Linux啓動,這一部分我想就可以略過了,無非是Linux的Bootloader,Kernel,Driver之類的,在這裏唯一要提到的就是ServiceManager,即服務管理器,這個是做爲一個進程在Android加載之前就被啓動了,我們可以從init.rc中看到這個配置項:

service servicemanager /system/bin/servicemanager

ServiceManager是Binder的服務管理守護進程,是Binder的核心,由其使用Binder驅動進行IPC管理,關於IPC通訊的機制,此處不再詳述。在APP和Framework中,應用程序使用的ServiceManager.java就是通過Proxy與這個守護進程進行的通訊。

然後是Android的啓動,接下來要詳細描述的部分。我們還是先看一下init.rc中的配置

service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server

即linux啓動以後,啓動zygote服務進程,這個進程恰如其名:孵化器,是所有Android應用程序的孵化器。

我們來看一下app_process的代碼,位置是在:

frameworks/base/cmds/app_process/app_main.cpp

在main()函數中有如下代碼:

    if (0 == strcmp("--zygote", arg)) {

        bool startSystemServer = (i < argc) ?

                strcmp(argv[i], "--start-system-server") == 0 : false;

        setArgv0(argv0, "zygote");

        set_process_name("zygote");

        runtime.start("com.android.internal.os.ZygoteInit",

            startSystemServer);

    }

從中可以追蹤到AndroidRuntime,代碼位於:

frameworks/base/core/jni/AndroidRuntime.cpp

在start()函數中有如下代碼:

/* start the virtual machine */

if (startVm(&mJavaVM, &env) != 0)

    goto bail;

     ……

             env->CallStaticVoidMethod(startClass, startMeth, strArray);

即先啓動了虛擬機,然後利用JNI調用了zygoteInit函數。

繼續追蹤到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main()函數,代碼如下:

        if (argv[1].equals("true")) {

            startSystemServer();

        } else if (!argv[1].equals("false")) {

            throw new RuntimeException(argv[0] + USAGE_STRING);

        }



        Log.i(TAG, "Accepting command socket connections");



        if (ZYGOTE_FORK_MODE) {

            runForkMode();

        } else {

            runSelectLoopMode();

        }

前一部分是在啓動系統服務,後一部分是雖然是一個條件判斷,但ZYGOTE_FORK_MODE被賦了false,所以進行else分支的runSelectLoopMode()函數,在該函數中,實際上是在一死循環中利用zygoteConnection類通過socket的方式進行消息處理,用於fork出新的zygote,從而以最輕量級的方式實現每個進程一個虛擬機的機制。

繼續來看startSystemServer(),代碼位於:

frameworks/base/services/java/com/android/server/systemserver.java

在其main()函數中調用了init1(args)這個native函數,利用JNI機制,跟蹤至

frameworks/base/services/jni/com_android_server_systemService.cpp,然後到

frameworks/base/cmds/system_server/library/system_init.cpp

在system_init()函數中有如下代碼:

if (strcmp(propBuf, "1") == 0) {

    // Start the SurfaceFlinger

    SurfaceFlinger::instantiate();

}

AndroidRuntime* runtime = AndroidRuntime::getRuntime();



LOGI("System server: starting Android services./n");

runtime->callStatic("com/android/server/SystemServer", "init2");

即完成了SurfaceFlinger的實例化,然後利用運行時的callStatic()函數調用了SystemServer的init2()函數,這個函數位於:

frameworks/base/services/java/com/android/server/SystemServer.java

代碼是:

public static final void init2() {

    Slog.i(TAG, "Entered the Android system server!");

    Thread thr = new ServerThread();

    thr.setName("android.server.ServerThread");

    thr.start();

}

在這個ServerThread線程中,可以看到我們熟悉的Android服務了,比如WallpaperService服務的啓動:

        try {

            Slog.i(TAG, "Wallpaper Service");

            wallpaper = new WallpaperManagerService(context);

            ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);

        } catch (Throwable e) {

            Slog.e(TAG, "Failure starting Wallpaper Service", e);

        }

最後,調用各服務的systemReady()函數通知系統就緒。

至此,系統的啓動過程結束,借用兩張圖來說明問題:
這裏寫圖片描述

從這裏可以看出,linux的init在啓動若干守護進程之後,就啓動了Android的runtime和zygote,zygote再啓動虛擬機,系統服務,系統服務再啓動完本地服務後,又啓動了若干Android服務,並完成向ServiceManager的註冊工作,最後系統啓動完成。系統的進程空間如下圖所示:
這裏寫圖片描述

可見,由zygote孵化器爲各進程以寫時複製的方式用最小的代價實現了虛擬機。

好了,相信經過這一系列的源碼跟蹤,我們都能對Android的啓動過程有更清晰的認識,新年即將到來,在結束本系列文章的同時,祝大家新年快樂。

——歡迎轉載,轉載請註明來自於http://blog.csdn.net/caowenbin,謝謝——


發佈了69 篇原創文章 · 獲贊 39 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章