从某个方面来讲,我们可以将安卓看成是LINUX之上的一种XWINDOW。所以系统启动的过程难免要先从linux kernel开始讲起。当然linux kernel的启动不是我们这里需要讨论的问题。
本人最近试图在framework层添加一个自己的service,之前研究了一下但还不是特别清楚。故以此理清思路。也希望能够给同样在研究这部分的朋友好的提示。由于Android系统非常的庞大。所以要清晰的明白这些东西,一定要好好的研究它的实现机制。
Android系统在启动时首先会启动Linux基础系统,然后引导加载Linux Kernel并启动初始化进程(Init)。接着启动Linux守护进程。在启动Linux守护进程的同时还需要启动Zygote进程。包括初始化一个Dalvik虚拟机实例。装载Socket请求所需的类和监听。创建虚拟机实例来管理应用程序的进程。
在Zygote之后需要初始化runtime进程。在这个过程中主要进行服务管理器的初始化和注册。
Android在开机启动后,经过一系列的加载流程,将进入frameworks\base\cmds\app_process\app_main.cpp进而执行main()方法。
188 if (zygote) {
189 runtime.start("com.android.internal.os.ZygoteInit",
190 startSystemServer ? "start-system-server" : "");
191 } else if (className) {
192 // Remainder of args get passed to startup class main()
193 runtime.mClassName = className;
194 runtime.mArgC = argc - i;
195 runtime.mArgV = argv + i;
196 runtime.start("com.android.internal.os.RuntimeInit",
197 application ? "application" : "tool");
198 } else {
199 fprintf(stderr, "Error: no class name or --zygote supplied.\n");
200 app_usage();
201 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
202 return 10;
203 }
(在frameworks\base\core\jni文件夹下存在com_android_internel_os_ZygoteInit.cpp文件。在此文件中通过register_com_android_internel_os_ZygoteInit函数调用AndroidRuntime::registerNativeMethods函数。)
最终会调用到frameworks/base/core/jni/AndroidRuntime.cpp的start()方法。事实上,Android API与本地方法的注册关联就是在AndroidRuntime.cpp模块里完成的。
Android framework层的API函数对应的本地方法映射和注册原理简析:
Android启动之后,本地方法的注册关联是在调用AndroidRuntime::startReg过程中完成的。在AndroidRuntime的静态数组gRegJNI[]存储了各个framework子模块本地方法关联信息。数组gRegJNI[]的每一个元素存储了各个模块的注册相关的函数指针,这个函数指针的功能是把子模块中众多的本地函数关联添加进系统中。子模块中的众多本地函数也是通过子模块的静态数组被上述函数指针指向的函数作为参数来使用。注册的关联具体是通过在startReg中调用register_jni_process方法把静态数组gRegJNI[]数组存储的各个framework子模块本地方法关联信息注册到系统中。
具体的注册JNI的步骤简介:(待续)