源碼級分析Android系統啟動流程


首先看一下Android系統的體系結構,相信大家都不陌生

1.首先Bootloader引導程序啟動完Linux內核后,會加載各種驅動和數據結構,當有了驅動以后,開始啟動Android系統,同時會加載用戶級別的第一個進程init(system\core\init.c),該進程會首先加載一個init.rc配置文件,代碼如下

int main(int argc, char **argv)
    {
        
        // 創建文件夾 掛載
        mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
        mkdir("/dev/pts", 0755);
       
        // 打開日志
        log_init();
        
        INFO("reading config file\n");
        // 加載init.rc配置文件
        init_parse_config_file("/init.rc");
    
    } 

2.init.rc配置文件會進行很多的配置,創建很多的文件夾及文件,然后初始化一些Android驅動器,之后該配置文件最重要的一個任務就是啟動一個Zygote(孵化器)進程,此進程是Android系統的一個母進程,用來啟動Android的其他服務進程,代碼:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    socket zygote stream 666
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

3. Zygote會執行一個app_process可執行文件,在這個文件中首先添加了Android運行時環境,在Android運行時中調用了ZygoteInit.java,這就從c++代碼跳到了java代碼。

        int main(int argc, const char* const argv[])
    {
        ...
        // Android運行時環境
        AppRuntime runtime;
        ...
        // Next arg is startup classname or "--zygote"
        if (i < argc) {
            arg = argv[i++];
            if (0 == strcmp("--zygote", arg)) {
                bool startSystemServer = (i < argc) ? 
                        strcmp(argv[i], "--start-system-server") == 0 : false;
                setArgv0(argv0, "zygote");
                set_process_name("zygote");
                // 啟動java代碼
                runtime.start("com.android.internal.os.ZygoteInit",
             ...
    
    }

4.在ZytofeInit.java代碼中首先設置了Java虛擬機的堆內存空間,然后啟動一個類加載器加載Android啟動依賴的類比如Activity等四大組件,dialog等UI的類,然后分出一個子進程啟動SystemServer系統服務

  public static void main(String argv[]) {
        try {
            VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);

            // 加載Android依賴的類
            preloadClasses();
            //cacheRegisterMaps();
            preloadResources();
            ...

            if (argv[1].equals("true")) {
                // 啟動系統服務
                startSystemServer();
            } else if (!argv[1].equals("false")) {
           ...
    }


    private static boolean startSystemServer()
         ...
            args = new String[] {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
                "--capabilities=130104352,130104352",
                "--rlimit=8,",
                "--runtime-init",
                "--nice-name=system_server",
                "com.android.server.SystemServer",
          ...

            /* Request to fork the system server process */
            // 母進程開始分叉服務 啟動SystemServer
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, rlimits,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        ...
    }

5.在SystemServer.java代碼中有兩個方法init1()啟動Native世界,init2()啟動Android的Framework世界

    public static void main(String[] args) {
           ... 
        // 加載jni庫
        System.loadLibrary("android_servers");
        // 調用native方法,該方法啟動Native世界
        init1(args);
    }
    native public static void init1(String[] args);

6.SystemServer首先調用init1()方法加載JNI庫,啟動Native世界。init1通過System.loadLibrary("android-servers")加載一個類庫文件,其對應的源碼文件為com_android_server_SystemServer.cpp 其C++代碼如下,在該類庫中轉調了system_init()方法

    // 類似java的抽象方法
    extern "C" int system_init();
    
    static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
    {    
        // 轉調
        system_init();
    }
    
    /*
     * JNI registration.
     */
    static JNINativeMethod gMethods[] = {
        /* name, signature, funcPtr */ 
        // 函數指針 把init1方法映射到android_server_SystemServer_init1
        { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
    };

7.System_init方法在System_init.cpp中實現,它首先啟動系統的硬件服務,比如Audio、Camera等,啟動完硬件服務后它又通過Android運行時環境調用了SystemServer中的init2()方法,init2()方法啟動Framework世界,代碼如下:

    extern "C" status_t system_init()
    {
        ...
        // 啟動硬件的服務
        if (strcmp(propBuf, "1") == 0) {
            // Start the SurfaceFlinger
            SurfaceFlinger::instantiate();
        }
    
        
        
        AndroidRuntime* runtime = AndroidRuntime::getRuntime();
    
        LOGI("System server: starting Android services.\n");
        // 啟動完硬件服務后,又回到Systemserver的init2方法
        runtime->callStatic("com/android/server/SystemServer", "init2");
        ...
    }

8.SystemServer的init2方法,init2()方法啟動Android的Framework層,啟動Android世界。在該方法中啟動了一個ServerThread線程,其代碼如下:

    public static final void init2() {
            Slog.i(TAG, "Entered the Android system server!");
            Thread thr = new ServerThread();
            thr.setName("android.server.ServerThread");
            thr.start();
        }

9.init2()啟動的線程ServerThread中的的run方法中通過一個Looper開啟了Android中的各種服務比如LightService,PowerManagerService,BatteryService,WindowManagerService等,並將服務添加到ServiceManager中去管理,啟動完各種服務后,調用ActivityManagerService.systemReady方法:

 public void run() {
        ...
        // 開啟Android各種服務並且添加到ServiceManager去管理
        Slog.i(TAG, "Device Policy");
        devicePolicy = new DevicePolicyManagerService(context);
        ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, ottle = 

        ...
        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        // 各種服務開啟后調用ActivityManagerService.systemReady
        ((ActivityManagerService)ActivityManagerNative.getDefault())
                .systemReady(new Runnable() {
            public void run() {
                Slog.i(TAG, "Making services ready");

10.在ActivityManagerService的systemReady方法中打開Android系統的第一個Activity

    public void systemReady(final Runnable goingCallback) {
            ...
            // 打開第一個Activity
                mMainStack.resumeTopActivityLocked(null);
            }
        }

11.ActivityStack的resumeTopActivityLocked方法啟動home界面

    final boolean resumeTopActivityLocked(ActivityRecord prev) {
            // Find the first activity that is not finishing.
            // 沒有已經打開的Activity, next為 null
            ActivityRecord next = topRunningActivityLocked(null);
    
            // Remember how we'll process this pause/resume situation, and ensure
            // that the state is reset however we wind up proceeding.
            final boolean userLeaving = mUserLeaving;
            mUserLeaving = false;
    
            if (next == null) {
                // There are no more activities!  Let's just start up the
                // Launcher...

                if (mMainStack) {
                    // 啟動lucher應用的鎖屏界面
                    return mService.startHomeActivityLocked();
                }
            }

12.打開了Luncher應用的Home界面之后,到此Android系統啟動完成了。

可以把整個過程總結為如下這張圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM