`
1025250620
  • 浏览: 229862 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android深入浅出之Zygote(转)

 
阅读更多
[size=xx-small]Android深入浅出之Zygote

一 目的

zygote,是Android搞出来的一个东西。网上讲这个的也非常多。第一次看到这个名字我就挺郁闷,想干嘛这是?Linux下名字都取得挺通俗易懂,深得人心。zygote?不就想模仿Linux下的fork吗?个人觉得Google取名字挺怪,包括Google本身。
不管怎样,Zygote依然是Android系统的核心,zygote是受精卵的意思,可以认为是Android framework大家族的祖先!我们本节的目的是描述下zygote的来龙去脉,顺便揭露下它的短处,以后大家可以对症下药,变异一个更加优良的品种。
二 Zygote

zygote本身是一个应用层的程序,和驱动,内核模块之类的没点关系。这下大家放心点了吧?zygote的启动由linux的祖先init启动。这个在init分析中提过。这里就不说了。
zygote,ps中看到的进程名叫zygote,其最初的名字是app_process,通过直接调用pctrl把名字给改成了”zygote”。不过不影响我们分析。
zygote的代码在framework/base/cmds/app_process/App_main.cpp中。我们一步步来看。
既然是应用程序,直接看main咯。
[/size]
int main(int argc, const char* const argv[])

{

  //参数很重要啊,还记得init分析吗?

//恩,这几个参数就是:(一定要记住我们的情景分析方法!)

//zygote /system/bin/app_process

//-Xzygote /system/bin --zygote --start-system-server

// 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;

     //AppRuntime是个什么玩意儿?addVmArguments?好像和虚拟机有点关系喔

int i = runtime.addVmArguments(argc, argv);

[--->AppRuntime]
class AppRuntime : public AndroidRuntime

从AndroidRuntime中派生而来,是和dalvik交互的一个方便类,这里先不说了。
[---->main]
...

int i = runtime.addVmArguments(argc, argv);

....

if (i < argc) {

        arg = argv[i++];

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

            bool startSystemServer = (i < argc) ?

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

           //废话,根据我们的参数,startSystemServer=true

            setArgv0(argv0, "zygote");

         //改名字,不知道windows下的怎么改、linux下的可以用pctrl系统调用

            set_process_name("zygote");

            //start?记住我们的参数

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

                startSystemServer);

        }

    } else {

        return 10;

    }

FT,app_main还是很简单的,但是runtime.start看起来不简单啊,传进去的那个参数
“com.android.internal.os.ZygoteInit“挺像java类的命名规则。
2.1 AppRuntime

好了,代码进入到runtime.start("com.android.internal.os.ZygoteInit",true)了。source insight直接进去看看。代码在framework/base/core/jni/AppRuntime.cpp中。
[--->void AndroidRuntime::start()]
void AndroidRuntime::start(const char* className, const bool startSystemServer)

{

    LOGD("/n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<</n");

    char* slashClassName = NULL;

    char* cp;

    JNIEnv* env;

   //linux下signal的处理,没什么好说的

    blockSigpipe();

   //设置环境变量ANDROID_ROOT为/system

     const char* rootDir = getenv("ANDROID_ROOT");

    if (rootDir == NULL) {

        rootDir = "/system";

       setenv("ANDROID_ROOT", rootDir, 1);

    }



   /*启动虚拟机*/

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

        goto bail;

启动虚拟机,和JAVA有关系了吧?Android最重要的sdk都是java,那虚拟机这部分肯定要进去看看的。
[--->int AndroidRuntime::startVm()]
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)

{

//唉,大部分都是设置java虚拟机的启动参数。不过有几个参数比较重要。



//checkjni,可能没使用过jni的一辈子都不能体会

//说白了,就是我们在C++层调用jni函数的时候,会对参数或者什么的进行检查

//要是不合法的话,直接把虚拟机exit!第一个影响速度,第二个是影响程序。

//这个只作为开发时候使用。

    property_get("dalvik.vm.checkjni", propBuf, "");

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

        checkJni = true;

    } else if (strcmp(propBuf, "false") != 0) {

        /* property is neither true nor false; fall back on kernel parameter */

        property_get("ro.kernel.android.checkjni", propBuf, "");

        if (propBuf[0] == '1') {

            checkJni = true;

        }

    }

   //设置虚拟机最大heapsize,才给16M,似乎有点少,尤其是在做图片操作的

  //随便一个几百兆的图片就会把虚拟机搞死。

    strcpy(heapsizeOptsBuf, "-Xmx");

    property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");

    opt.optionString = heapsizeOptsBuf;

    mOptions.add(opt);



    LOGD("CheckJNI is %s/n", checkJni ? "ON" : "OFF");

    if (checkJni) {

        /* extended JNI checking */

        opt.optionString = "-Xcheck:jni";

        mOptions.add(opt);



        /* set a cap on JNI global references */

        opt.optionString = "-Xjnigreflimit:2000";

        mOptions.add(opt);

   }

//具体dalvik虚拟机有哪些参数,可以参考Dalvik的说明

//反正调用了下面这个函数,虚拟机就按您指定的参数启动了。

   if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {

        LOGE("JNI_CreateJavaVM failed/n");

        goto bail;

    }



    result = 0;



bail:

    free(stackTraceFile);

    return result;

}

OK,虚拟机起来了,看看我们在runtime.start中还要做什么
[--->void AndroidRuntime::start()]
  if (startVm(&mJavaVM, &env) != 0)

     ...

//startReg?

if (startReg(env) < 0) {

        goto bail;

}

看看去。
[--->int AndroidRuntime::startReg()]
为何不把startReg改成startRegister()。
int AndroidRuntime::startReg(JNIEnv* env)

{

   //这个名字还是很清楚的,设置创建线程的函数为javaCreateThreadEtc

androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

//JNI知识,自己去查JDK

    env->PushLocalFrame(200);

    //

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {

        env->PopLocalFrame(NULL);

        return -1;

    }

    env->PopLocalFrame(NULL);

    //搞笑,下面的注释为何不干掉?

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;

}

[---->static int register_jni_procs()]
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)

{

    for (size_t i = 0; i < count; i++) {

        if (array[i].mProc(env) < 0) {//啥都没干,由传进来的参数控制..浪费我时间。

        return -1;

        }

    }

    return 0;

}

回到之前的调用,
register_jni_procs(gRegJNI, NELEM(gRegJNI), env),它的参数gRegJNI是下面这个结构
static const RegJNIRec gRegJNI[] = {

    REG_JNI(register_android_debug_JNITest),

    REG_JNI(register_com_android_internal_os_RuntimeInit),

    REG_JNI(register_android_os_SystemClock),

    REG_JNI(register_android_util_EventLog),

    REG_JNI(register_android_util_Log),

...后面还有很多,好像是一些函数

};

随便挑一个跟进去看看。
[--->int register_android_debug_JNITest]
int register_android_debug_JNITest(JNIEnv* env)

{

    return jniRegisterNativeMethods(env, "android/debug/JNITest",

        gMethods, NELEM(gMethods));

}

其实就是注册一些JAVA中native函数在C++层对应的实行函数。
所以说:
如果你可以在这个地方加上你定制的东西。
好了,startReg完了,回到runtime.start。
[---->void AndroidRuntime::start]
    if (startReg(env) < 0) {

        goto bail;

    }



   jclass stringClass;

    jobjectArray strArray;

    jstring classNameStr;

    jstring startSystemServerStr;

 



//下面这些话,都是把c++的字符串转成JAVA的字符串

//

stringClass = env->FindClass("java/lang/String");

//构造一个String数组,元素个数为2

    strArray = env->NewObjectArray(2, stringClass, NULL);

    classNameStr = env->NewStringUTF(className);

    env->SetObjectArrayElement(strArray, 0, classNameStr);

    startSystemServerStr = env->NewStringUTF(startSystemServer ? "true" : "false");

    env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

//java应用程序不也有main函数吗?上面的就是把C++传进来的参数,变成java的参数

[

  “com.android.internal.os.ZygoteInit”,

  “true”

]

    jclass startClass;

    jmethodID startMeth;

   //

     startClass = env->FindClass(slashClassName);

// 下面这个JNI调用,就真正进入java层了

     startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");

//下面调用的就是com.android.internal.os.ZygoteInit类的main函数

//最后一个参数是true

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

bail:

    free(slashClassName);

}
分享到:
评论

相关推荐

    Android Zygote启动流程源码解析

    了解Zygote的启动流程对于深入理解Android底层机制具有重要意义。 #### Zygote进程概述 Zygote进程可以被看作是Android世界的“创世者”,所有应用进程以及SystemServer进程都是通过Zygote进程fork而来的。虽然...

    Android启动-Zygote启动介绍

    Android启动,第二大阶段,Zygote启动。 紧接上一篇《 Android启动-init介绍》Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote等。 这里我们就来研究一下Zygote启动过程。

    sundy深入浅出部分源码android

    《Sundy深入浅出部分源码Android》是一个关于Android源码解析的学习资源,旨在帮助开发者更深入地理解Android系统的运行机制。在这个专题中,Sundy将带领我们逐步探索Android的内部工作原理,通过分析关键源码,提升...

    深入浅出 google android(源码)

    《深入浅出 Google Android》是一本专为Android开发者和爱好者准备的深度解析书籍,它涵盖了Android系统的源码分析,帮助读者理解Android系统的工作原理。这本书从第四章开始,逐步带领读者深入Android的世界,通过...

    zygote

    Zygote是所有Android进程的始祖,它预先加载了核心库,并初始化了一些系统服务,当需要运行新的Android应用时,会从Zygote进程中 fork 出一个新的进程。 在Android系统启动时,zygote进程首先被创建。这个过程包括...

    王家林的NoSQL架构揭秘和MongoDB深入浅出最佳实践

    根据给定文件的信息,我们可以提炼出以下...综上所述,这些知识点不仅涵盖了Android系统移植与框架整合的基础理论,还包括了具体的技术实现细节,非常适合希望深入了解Android系统架构和服务开发的专业人士学习和研究。

    模拟Android系统Zygote启动流程

    在Android操作系统中,Zygote进程是整个系统的核心部分,它是所有Android应用程序进程的始祖。Zygote的启动流程非常关键,因为它涉及到系统资源的初始化、Dalvik或ART虚拟机的预加载以及核心库的加载等。让我们深入...

    Android Zygote解析

    在这个过程中,Zygote首先会初始化Dalvik(在较早的Android版本中)或ART(在现代Android版本中)虚拟机,使得Java应用程序能够在Linux内核之上运行。 Android应用程序由Java编写,不能直接作为本地进程在Linux系统...

    Android框架浅谈

    4. **Zygote进程与SystemServer启动**:Zygote进程是Android系统中的一个特殊进程,它的主要作用是在系统启动时预加载Dalvik虚拟机,以及后续根据需要fork出应用程序的进程。SystemServer进程则是由Zygote进程fork...

    Android系统进程Zygote启动过程的源代码分析.pdf

    该文深入到Android源代码的多个层次,包含对关键组件如SystemServer、ActivityManagerService、以及Zygote进程自身启动过程的分析。接下来将详细分析文章中所涉及的技术知识点。 首先,Zygote是Android系统中的一个...

    zygote启动过程

    ### zygote启动过程详解 #### 一、zygote启动背景及意义 在深入了解zygote启动过程之前,我们先来简述一下zygote的重要性。zygote是Android系统中...理解zygote的工作原理对于深入掌握Android系统架构有着重要意义。

    详细分析Android中实现Zygote的

    在Android系统中,Zygote进程扮演着至关重要的角色,它是所有应用程序进程和System进程的始祖,被誉为“进程孵化器”。Zygote通过自我复制的方式创建新的进程,从而确保每个新进程都能快速拥有一个预先加载好的...

    zygote源码分析

    zygote是Android系统中的一个核心组件,它的主要任务是孵化(zygote即受精卵之意,象征新生命的开始)Dalvik或ART虚拟机进程,并为其他Android应用提供预加载的服务。理解zygote的工作原理对于深入学习Android系统运行...

    Zygote启动流程-systemServer启动流程-homeLauncher启动

    通过对Zygote启动流程以及systemServer和Home Activity启动过程的详细解析,我们不仅了解了Android系统启动过程中的关键步骤和技术细节,还深入了解了ART虚拟机的工作原理。这些深入的理解对于开发者来说至关重要,...

    Android 8.1zygote服务 SystemServer启动流程 Activity创建

    Android zygote服务/SystemServer启动流程/Activity创建,本文档继承Android init的分析,继续往下分析Zygote进程、SystemServer进程的创建、Activity的建立

    Android 系统启动流分析 & Zygote启动流程分析

    Zygote在Android系统扮演着不可或缺的角色,Android系统的启动首先需要Zygote参与,比如启动SystemService , 还有一个就是孵化应用的进程,比如我们创建一个Activity也是需要Zygote参与.  Zygote 启动分为两个部分: 1....

    《深入理解Android(卷1)》

    总之,《深入理解Android(卷1)》是一本全面而深入的Android技术指南,无论你是初学者还是有经验的开发者,都能从中获益匪浅。结合书中详尽的解释和实际案例,你可以逐步建立起对Android系统深层运作的深刻认识。

    深入理解Android 卷1.pdf

    一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际应用开发需求,书中所涵盖...

Global site tag (gtag.js) - Google Analytics