android 启动过程分析

本文探讨了Android系统的启动过程,重点分析了如何通过cpp程序/app_main.cpp启动Dalvik虚拟机。内容涉及AppRuntime类的继承结构,AndroidRuntime在dalvik虚拟机中的作用,以及启动过程中对虚拟机heap大小的设定。文章引用了柯元旦和邓凡平两位老师的著作,并提及Skia图形库在Android中的应用。

关于android启动分析的文章 是拜读柯元旦老师的android内核剖析 与 邓凡平老师的深入理解android 自己读源码按图索骥的成果。

在这里感谢 两位老师的不辞辛劳把知识奉献出来与大家分享!


android是基于linux的所以dalvik虚拟启动必须通过服务或是通过某个程序来启动

android的dalvik虚拟机是通过cpp程序来启动

程序名为:/framworks/base/cdms/app_process/app_main.cpp  app_main 在编译的时候 被定义成了app_process 

android.mk:

LOCAL_MODULE:= app_process

所以在init.rc里面 是通过下边的这段配置来启动app_main的

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_main的main函数吧

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

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

    // Next arg is parent directory
    if (i < argc) {
        runtime.mParentDir = argv[i++];
    }

    // Next arg is startup classname or "--zygote"
    if (i < argc) {
        arg = argv[i++];
        //从这个参数来看 如果有 --zygote参数就是启动一个新的虚拟机 否则就是重新启动
        if (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ? 
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            //哈这里就是启动dalvik虚拟机 去 runtime里面看看吧
            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;
    }

}

接下来分析AppRuntime类吧。

AppRuntime是在app_main.cpp中定义的 继承了AndroidRuntime 主要功能实现在AndroidRuntime 中

AndroidRuntime 实现是frameworks/base/core/jni/ 这个已经定义在jni目录了 看来以后运行在dalvik虚拟机中的java程序也需要调用此类

先看看AndroidRuntime的构造方法吧

AndroidRuntime::AndroidRuntime()
{
    SkGraphics::Init();
    // this sets our preference for 16bit images during decode
    // in case the src is opaque and 24bit
    SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
    // This cache is shared between browser native images, and java "purgeable"
    // bitmaps. This globalpool is for images that do not either use the java
    // heap, or are not backed by ashmem. See BitmapFactory.cpp for the key
    // java call site.
    SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
    // There is also a global font cache, but its budget is specified in code
    // see SkFontHost_android.cpp

    // Pre-allocate enough space to hold a fair number of options.
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}

百度出来的 Skia的信息 记录下吧

skia是个2D向量图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现。不仅用于Google Chrome浏览器,新兴的Android开放手机平台也采用skia作为绘图处理,搭配OpenGL/ES与特定的硬件特征,强化显示的效果


会来继续看app_main.cpp的main方法

runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);
这个调用AndroidRuntime::start方法来进入java世界

AndroidRuntime::start主要内容是根据配置的虚拟机参数 来启动dalvik虚拟机 其中dalvik虚拟机的heap大小就是在这里设置的 并运行 

com.android.internal.os.ZygoteInit.main方法 进入java世界的第一个类就是 
com.android.internal.os.ZygoteInit







                
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值