亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當(dāng)前位置: > 華清遠(yuǎn)見教育科技集團(tuán) > 嵌入式學(xué)習(xí) > 講師博文 > Android本地服務(wù)的啟動(dòng)
Android本地服務(wù)的啟動(dòng)
時(shí)間:2016-12-12作者:華清遠(yuǎn)見

通過上一節(jié)Android init進(jìn)程啟動(dòng)的分析可知,init進(jìn)程在啟動(dòng)過程中,解析并處理了init.rc和init.hardware.rc兩個(gè)初始化腳本文件,在兩個(gè)初始化腳本文件里,定義了一系列的service section,這些service在boot觸發(fā)器下,通過class_start default依次啟動(dòng),其過程總結(jié)如下:

1. init 解析init.rc

2. init 將init.rc里的service放到隊(duì)列里面等待觸發(fā)器的觸發(fā)

3. init通過 action_for_each_trigger("boot", action_add_queue_tail);觸發(fā)boot Action

4. 依次執(zhí)行boot下的Commands,包括class_start default命令

5. 所有的service默認(rèn)的class為默認(rèn)值:default,所以,所有init.rc中的service都被啟動(dòng)

zygote服務(wù)啟動(dòng)

通過init.rc中對zygote服務(wù)的描述可知,其對應(yīng)的程序?yàn)椋?system/bin/app_process
        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

該服務(wù)會(huì)在on boot時(shí)觸發(fā),其程序?yàn)?system/bin/app_process,服務(wù)名為zygote,-Xzygote /system/bin --zygote --start-system-server為參數(shù)列表。

在創(chuàng)建了zygote 服務(wù)后,在目錄下建立一個(gè)stream socket文件/dev/socket/zygote,權(quán)限為666,當(dāng)zygote服務(wù)重啟時(shí),重啟media服務(wù)

通過find ./ -name Android.mk -exec grep -l app_process {} \; 命令,查找到,它在./frameworks/base/cmds/app_process/目錄中被編譯,其主要入口文件為:

./frameworks/base/cmds/app_process/app_main.cpp

找到該程序的main入口函數(shù),

int main(int argc, const char* const argv[])
    {
        // These are global variables in ProcessState.cpp
        mArgC = argc;
        mArgV = argv;
        mArgLen = 0;
        for (int i=0; i< argc; i++) {
            mArgLen += strlen(argv[i]) + 1;
            }
        mArgLen--;
        AppRuntime runtime;
        const char *arg;
        const char *argv0;
        argv0 = argv[0];
        // Process command line arguments
        // ignore argv[0]
        argc--;
        argv++;
        // Everything up to '--' or first non '-' arg goes to the vm
        // 在zygote服務(wù)的參數(shù)列表中,以'--和非'-'開頭的參數(shù),是dalvik的參數(shù):/system/bin--zygote --start-system-server,交給Vm來處理
        int i = runtime.addVmArguments(argc, argv);
        // 找到zygote的目錄:/system/bin
        if (i < argc) {
            runtime.mParentDir = argv[i++];
        }
        // 如果接下來的參數(shù)是:--zygote --start-system-server的話,設(shè)置argv0="zygote",startSystemServer= true,啟動(dòng)java VM
        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");
                runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);
        } else {
            set_process_name(argv0);
            runtime.mClassName = arg;
            // Remainder of args get passed to startup class main()
            runtime.mArgC = argc-i;
            runtime.mArgV = argv+i;
            LOGV("App process is starting with pid=%d, class=%s.\n",
            getpid(), runtime.getClassName());
            runtime.start();
            }
        } else {
                LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
                fprintf(stderr, "Error: no class name or --zygote supplied.\n");
                app_usage();
                return 10;
        &nbnbsp;   }
    }

根據(jù)service zygote的參數(shù),啟動(dòng)VM:

runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

runtime是AppRuntime的對象,AppRuntime是AndroidRuntime的子類:

runtime.start方法在AndroidRuntime里實(shí)現(xiàn):

void AndroidRuntime::start(const char* className, const bool startSystemServer)
    {
        LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");        //logcat里顯眼的字樣
        char* slashClassName = NULL;
        char* cp;
        JNIEnv* env;
        blockSigpipe();
        /*
        * 'startSystemServer == true' means runtime is obslete and not run from
        * init.rc anymore, so we print out the boot start event here.
        */
        if (startSystemServer) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
        const char* rootDir = getenv("ANDROID_ROOT"); // 取得Android的根目錄:/system
        if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
        LOG_FATAL("No root directory specified, and /android does not exist.");
        goto bail;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
        }
        //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
        //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
        /* start the virtual machine */
        // 啟動(dòng)Dalvik虛擬機(jī),在AndroidRuntime::startVm方法中,設(shè)備了大量VM的參數(shù),后調(diào)用JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs),通過JNI啟動(dòng)虛擬機(jī)
        if (startVm(&mJavaVM, &env) != 0)
        goto bail;
        /*
        * Register android functions.
        */
        if (startReg(env) < 0) { // 注冊系統(tǒng)使用的JNI函數(shù)
        LOGE("Unable to register all android natives\n");
        goto bail;
        }         jclass stringClass;
        jobjectArray strArray;
        jstring classNameStr;
        jstring startSystemServerStr;
        stringClass = env->FindClass("java/lang/String");        // 從Dalvik虛擬機(jī)里,查找到String類,
        assert(stringClass != NULL);         strArray = env->NewObjectArray(2, stringClass, NULL);        // 創(chuàng)建一個(gè)String數(shù)組,有兩個(gè)元素(strArray = new String[2])
        assert(strArray != NULL);
        classNameStr = env->NewStringUTF(className);        // 創(chuàng)建一個(gè)Java String對象,初始值為:className,其實(shí)是start第一個(gè)參數(shù):com.android.internal.os.ZygoteInit
        assert(classNameStr != NULL);
        env->SetObjectArrayElement(strArray, 0, classNameStr);        // 設(shè)置strArray 第一個(gè)元素的值為:classNameStr (strArray[0] =classNameStr)
        startSystemServerStr = env->NewStringUTF(startSystemServer ? "true" : "false");        // 創(chuàng)建一個(gè)Java String對象,初始值為:startSystemServer ,其實(shí)是start第二個(gè)參數(shù):true
        env->SetObjectArrayElement(strArray, 1, startSystemServerStr);        // 設(shè)置strArray 第二個(gè)元素的值為:strArray[1] =startSystemServerStr
        /*
        * Start VM. This thread becomes the main thread of the VM, and will
        * not return until the VM exits.
        */
        // 根據(jù)上面的解釋可知:準(zhǔn)備啟動(dòng)Java VM,并且創(chuàng)建VM的主線程,只要VM不退出,這個(gè)主線程一直運(yùn)行。
        jclass startClass;
        jmethodID startMeth;
        for (cp = slashClassName; *cp != '\0'; cp++)        //
將com.android.internal.os.ZygoteInit中的包分隔符'.'換成'/'即:com/android/internal/os/ZygoteInit
        if (*cp == '.')
        *cp = '/';
        startClass = env->FindClass(slashClassName);         // 從VM中查找ZygoteInit類,難道它要在VM里加載這個(gè)類。。。。
        if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
        } else {
        startMeth = env->GetStaticMethodID(startClass, "main",
        "([Ljava/lang/String;)V"); //
        查找到com/android/internal/os/ZygoteInit類中的main方法ID,接合Java文件命名規(guī)則,你能更深刻的理解,為什么主類名要和文件名一致,并且main方法為static方法。
        if (startMeth == NULL) {
        LOGE("JavaVM unable to find main() in '%s'\n", className);
        /* keep going */
        } else {
        env->CallStaticVoidMethod(startClass, startMeth, strArray);        // 調(diào)用ZygoteInit類里的main方法,這不是運(yùn)行ZygoteInit這個(gè)JAVA程序嗎!!
        #if 0
        if (env->ExceptionCheck())
        threadExitUncaughtException(env);
        #endif
            }
        }
        LOGD("Shutting down VM\n");
        if (mJavaVM->DetachCurrentThread() != JNI_OK)
        LOGW("Warning: unable to detach main thread\n");
        if (mJavaVM->DestroyJavaVM() != 0)
        LOGW("Warning: VM did not shut down cleanly\n");
        bail:
        free(slashClassName);
    }

由上面的分析可知,AndroidRuntime::start方法實(shí)現(xiàn)了下面功能:

1> 通過startVm來啟動(dòng)虛擬機(jī),并且注冊了一些系統(tǒng)JNI函數(shù),由于這個(gè)時(shí)候VM里還沒有程序,只是個(gè)空的VM執(zhí)行環(huán)境

2> 通過AndroidRuntime::start的參數(shù),在JNI代碼里構(gòu)建第一個(gè)Java程序ZygoteInit,將其作為VM的主線程,同時(shí)給其傳遞兩個(gè)JNI構(gòu)建的參數(shù):

"com/android/internal/os/ZygoteInit"和"true"

總結(jié):

Android系統(tǒng)的啟動(dòng)是由init進(jìn)程加載并啟動(dòng)了里面的/system/bin/app_process程序作為zygote服務(wù),然后在zygote服務(wù)里執(zhí)行runtime.start啟動(dòng)Dalvik虛擬機(jī),加載了ZygoteInit類作為Dalvik虛擬機(jī)的第一個(gè)主線程。至此,Android的Java運(yùn)行環(huán)境就準(zhǔn)備完畢了。

發(fā)表評論
評論列表(網(wǎng)友評論僅供網(wǎng)友表達(dá)個(gè)人看法,并不表明本站同意其觀點(diǎn)或證實(shí)其描述)
主站蜘蛛池模板: 精品视频在线免费看 | a级毛片在线 | 国产亚洲人成a在线v网站 | 婷婷成人综合 | 中文字幕久久精品波多野结 | jizzz日本| 91久久国产精品 | 九九热免费 | 天天操夜夜骑 | 久草久草久草久草 | 狠狠色综合久久久久尤物 | 欧美成人18性 | jizzjizz日本护士18 | 国产精品手机视频一区二区 | 狠狠色噜噜综合社区 | 理论片一区 | 九九色网 | 狼人 成人 综合 亚洲 | 一本一本久久a久久综合精品蜜桃 | 久久99热精品这里久久精品 | 久久亚洲欧美日本精品品 | 天天天天做夜夜夜做 | 青青草国产精品视频 | 日日干干 | 人人添人人添人人谢 | 在线播放国产色视频在线 | 欧美一区二区三区婷婷月色 | 成人在线观看视频免费 | 亚洲一区二区约美女探花 | 国产夫妻精品 | 欧美午夜在线 | 免费成人激情视频 | 日本欧美高清视频 | 国产欧美精品一区二区三区-老狼 | 精品一区二区三区免费毛片爱 | 久久久91精品国产一区二区 | 日本黄色大片网站 | 欧美一区二区在线播放 | 久久riav| 亚洲国产模特在线播放 | 久久的色偷偷 |