Android 系统分析

 ANDROID搞了大概5个月了,总感觉到它的这个java封装非常的不爽。这次下载了Froyo的源码,准备好好分析下Android的运行流程。一直有个暗想–能否替换掉JAVA层?搞android最麻烦的就是老记不住它那几个文件的位置,这里将给出详细的路径,方便其他看客了解。

没有固定的顺序,不过大概就是从启动开始的一些东西吧。我的想法是对android了解越多,才越可能在此基础上做最好最完善的改动。真的很不喜欢它的java层。

 

一 用户空间init

我这里不分析linux启动的那第一个程序init。

 init代码在/system/core/init/init.c。感兴趣的可从main函数开始分析

android的其他重要进程都是init加载init.rc配置文件来fork的。其中,最重要的init.rc位于source/system/core/rootdir下。

init.rc有它特有的语法,可google一下就知道了。

 

二 zygote的诞生

 

zygote程序是有app_process弄出来的,app_process的启动在init.rc中有对应行。

service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server

//第一个zygote是这个服务的名字,实际启动的程序位于system/bin下的app_process,后面是这个程序的启动参数    socket zygote stream 666

//这个表示init将创建一个unix域的socket,666是rwx的读写执行权限。
    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中。

下面分析它的mian函数。

int main(int argc, const char* const argv[])
{
//argc =  5
//argv=["/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
    const char *arg;
    const char *argv0;

    argv0 = argv[0]; //argv0="/system/bin/app_process"

    // 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);//将参数加到虚拟机,待会分析,应该是把-Xzygote加入虚拟机了

    // Next arg is parent directory
    if (i < argc) {
        runtime.mParentDir = argv[i++]; //设置父目录为/system/bin 
    }
 //
    // 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;//正常情况是true
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);//启动java的zygoteInit
        } 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;
    }

}

从上面代码注释可以看出,很多工作都交给了Runtime对象来处理,这个runtime对象也是在这个cpp文件中定义的。我们来看一下。

class AppRuntime : public AndroidRuntime //基类是AndroidRuntime,待会分析下是干嘛的
{
public:
    AppRuntime()
        : mParentDir(NULL)
        , mClassName(NULL)
        , mArgC(0)
        , mArgV(NULL)
    {
    }

#if 0
    // this appears to be unused
    const char* getParentDir() const
    {
        return mParentDir;
    }
#endif

    const char* getClassName() const
    {
        return mClassName;
    }

    virtual void onStarted() //下面几个onXXX应该是回调用的,可能是JNI回调
    {
        sp<ProcessState> proc = ProcessState::self();
        if (proc->supportsProcesses()) {
            LOGV("App process: starting thread pool./n");
            proc->startThreadPool();
        }
        
        app_init(mClassName, mArgC, mArgV);

        if (ProcessState::self()->supportsProcesses()) {
            IPCThreadState::self()->stopProcess();
        }
    }

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        if (proc->supportsProcesses()) {
            LOGV("App process: starting thread pool./n");
            proc->startThreadPool();
        }       
    }

    virtual void onExit(int code)
    {
        if (mClassName == NULL) {
            // if zygote
            if (ProcessState::self()->supportsProcesses()) {
                IPCThreadState::self()->stopProcess();
            }
        }

        AndroidRuntime::onExit(code);
    }

    
    const char* mParentDir;
    const char* mClassName;
    int mArgC;
    const char* const* mArgV;
};

}

其中,基类AndroidRuntime.h在frameworks/base/include/android_runtime/AndroidRuntime.h中定义。大概看看里边都定义了些什么。

namespace android {
//这个类是与java虚拟机交互的一个类。
//估计java虚拟机由它启动了    
class AndroidRuntime
{
public:
    AndroidRuntime();
    virtual ~AndroidRuntime();

    /**
     * Register a set of methods in the specified class.
     */
    static int registerNativeMethods(JNIEnv* env,
        const char* className, const JNINativeMethod* gMethods, int numMethods);

    /**
     * Call a static Java function that takes no arguments and returns void.
     */
    status_t callStatic(const char* className, const char* methodName);

    /**
     * Call a class's static main method with the given arguments,
     */
    status_t callMain(const char* className, int argc, const char* const argv[]);

    /**
     * Find a class, with the input either of the form 
     * "package/class" or "package.class".
     */
    static jclass findClass(JNIEnv* env, const char* className);

    int addVmArguments(int argc, const char* const argv[]);

    void start(const char *classname, const bool startSystemServer);
    void start();       // start in android.util.RuntimeInit

    static AndroidRuntime* getRuntime();
    
    /**
     * This gets called after the JavaVM has initialized.  Override it
     * with the system's native entry point.
     */
    virtual void onStarted() = 0;

    /**
     * This gets called after the JavaVM has initialized after a Zygote
     * fork. Override it to initialize threads, etc. Upon return, the
     * correct static main will be invoked.
     */
    virtual void onZygoteInit() {};


    /**
     * Called when the Java application exits.  The default
     * implementation calls exit(code).
     */
    virtual void onExit(int code);

    /** create a new thread that is visible from Java */
    static void createJavaThread(const char* name, void (*start)(void *),
        void* arg);

    /** return a pointer to the VM running in this process */
    static JavaVM* getJavaVM() { return mJavaVM; }

    /** return a pointer to the JNIEnv pointer for this thread */
    static JNIEnv* getJNIEnv();

private:
    static int startReg(JNIEnv* env);
    int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);

    Vector<JavaVMOption> mOptions;

    /* JNI JavaVM pointer */
    static JavaVM* mJavaVM;

    /*
     * Thread creation helpers.
     */
    static int javaCreateThreadEtc(
                                android_thread_func_t entryFunction, 
                                void* userData,
                                const char* threadName,
                                int32_t threadPriority,
                                size_t threadStackSize,
                                android_thread_id_t* threadId);
    static int javaThreadShell(void* args);
};

// Returns the Unix file descriptor for a ParcelFileDescriptor object
extern int getParcelFileDescriptorFD(JNIEnv* env, jobject object);

}

AndroidRuntime类主要是和java打交道,而且好像只能由framework调用才能起作用,一般我自己的jni库都不用AndroidRuntime里边定义的方便函数,虽然都是static。原因如下(必须看看它的实现文件才知道原因)

//看来系统有一个全局的mJavaVM
JavaVM* AndroidRuntime::mJavaVM = NULL;
//整个系统范围内,第一次调用构造函数的应该就是在app_process中的吧?!
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;
}
//刚才那几个onXXX函数就是在这里调用的,估计是java层调用的
static void com_android_internal_os_RuntimeInit_finishInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onStarted();
}

static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

static jint com_android_internal_os_RuntimeInit_isComputerOn(JNIEnv* env, jobject clazz)
{
    return 1;
}

static void com_android_internal_os_RuntimeInit_turnComputerOn(JNIEnv* env, jobject clazz)
{
}

static jint com_android_internal_os_RuntimeInit_getQwertyKeyboard(JNIEnv* env, jobject clazz)
{
    char* value = getenv("qwerty");
    if (value != NULL && strcmp(value, "true") == 0) {
        return 1;
    }
    
    return 0;
}
//略去一些
int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
{
    int i;
    
    for (i = 0; i<argc; i++) {
        if (argv[i][0] != '-') {
            return i;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            return i+1;
        }
  //此时虚拟机还没有起来,先把这些options保存起来
        JavaVMOption opt;
        memset(&opt, 0, sizeof(opt));
        opt.optionString = (char*)argv[i];
        mOptions.add(opt);
    }
    return i;
}

该cpp位置在/frameworks/base/core/jni/AndroidRuntime.cpp中。

 回到app_process的main中,此处已运到到runtime.start(“com.android.internal.os.ZygoteInit”, startSystemServer)这句话来了,应进去看看start到底干了什么。

说来说去,不如看代码分析。

 

 

    原文作者:Android源码分析
    原文地址: https://juejin.im/entry/5a72a81d6fb9a01c9a271381
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞