본문 바로가기

개발관련/안드로이드 정리 ( update file )

Zygote

* Dalvik virtual machin 초기화 및 구동

   

// system/core/rootdir/init.rc

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

   

app_process 소스 ( /frameworks/base/cmds/app_process/app_main.cpp )

   

   

   

  • app_process main()

       

  1. AndroidRuntime 변수 셋팅 ( argument )

   

  1. runtime.start

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

   

app_process [java-options] cmd-dir start-class-name [options]

  • [java-options] : 가상 머신으로 전달
  • cmd-dir : 프로세스가 실행 될 디렉토리
  • start-class-name : 가상 머신에서 생성할 클래스의 이름.
  • [options] : 실행 될 클래스로 전달 될 옵션

   

AppRuntime 은 AndroidRuntime 상속 ( app_process.cpp 에 정의 되어 있음 )

( /frameworks/base/core/jni/AndroidRuntime.cpp )

   

  • AndroidRuntime::start

   

void AndroidRuntime::start(const char* className, const bool startSystemServer)

{

…

/*

Create a new VM instance
dalvik.vm.xxx 프로퍼티 초기화 ( property_get을 통한 기본 값 설정 )

JNI_CreateJavaVM ( /dalvik/vm/Jni.c )

*/

    startVm(&mJavaVM, &env);

…

/*
    가상 머신에서 사용 할 JNI 함수 등록
    gRegJNI 에 등록되어 있는 함수 호출

    코드 - ( /frameworks/base/core/jni/*.cpp )
*/

    startReg(env);

…

/*
    ZygoteInit 클래스 실행
    인자로 넘어 온 ZygoteInit의 main 함수 호출
*/

    jclass startClass;
    jmethodID startMeth;

    slashClassName = strdup(className);

    for (cp = slashClassName; *cp != '\0'; cp++)
        if (*cp == '.')
            *cp = '/'; 

    startClass = env->FindClass(slashClassName);

    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
        startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }
}

   

  • ZygoteInit

    ( /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java )

       

public static void main(String argv[]) {

    try {

        …

        /*

        새로운 어플 요청 처리를 위한 소켓 바인딩
        init.rc 를 통해 생성 된 zygote 소켓 사용 ( /dev/socket/zygote )

        init.rc - service ( socket 참고 )

        */

        registerZygoteSocket();

        /*

        애플리케이션 프레임워크에서 사용 할 클래스와 리소스 로딩
        새로 생성 되는 프로세스에서 그대로 사용 ( 애플리케이션 빠르게 생성 가능 )

        preloadClasses()
        preloaded-classes 에 미리 로딩 할 클래스가 정의 되어 있음

        ( /frameworks/base/preloaded-classes )

        preloadResources()
        preloaded_drawables, preloaded_color_state_lists 로딩

        ( /frameworks/base/core/res/res/values/array.xml )

        */

        preloadClasses();

        preloadResources();

        /*

        garbage collection
        참고 - http://developer.android.com/reference/java/lang/Runtime.html

        */

        gc();

        /*
        startSystemServer
        참고 - start_service의 SystemServer
        */

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

            startSystemServer();

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

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

        }

        /*

        runForkMode or runSelectLoopMode
   
        ZYGOTE_FORK_MODE = false ( éclair, froyo )

        runForkMode

        xxx
   
        runSelectLoopMode

        등록 된 USD 모니터링
        애플리케이션 생성 요청시 처리
        */

        if (ZYGOTE_FORK_MODE) {

            runForkMode(); // never called

        } else {

            runSelectLoopMode();

        }

        closeServerSocket();

    } catch (MethodAndArgsCaller caller) {

        caller.run();

    } catch (RuntimeException ex) {

        closeServerSocket();

        throw ex;

    }

}