从Android(安卓)init.rc到SystemServer.java
转载地址:http://my.oschina.net/mopidick/blog/144975
在上面一篇文章中,我们已经学习了Android系统启动的脚本文件init.rc,知道了init.c是怎么样解析脚本的。
之前的两篇文章:
1、解析Init.rc:http://my.oschina.net/u/561492/blog/144730
2、Android WIFI源码解读:http://my.oschina.net/u/561492/blog/142487
其中的第二篇文章,是从SystemServer.java说起的,那么Android系统是怎么从系统的启动脚本文件init.rc到SystemServer的呢?
1、回到init.rc文件中:
service zygote /system/bin/app\_process -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 666onrestart write /sys/android\_power/request\_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd
service类型的section表示一个可执行程序,这里告诉init进程创建一个:zygote进程,其中可执行文件的位置在: /system/bin/app_process,后面跟的是需要传给app_process程序的参数。
app_process是一个可执行的程序,那么其源码在哪个位置呢?我们通过一下命令来查看:
ubuntu@ubuntu:~/android/source$ find ./ -name Android.mk | xargs grep app_process./frameworks/base/cmds/app_process/Android.mk:LOCAL_MODULE:= app_process
可以看到,生成app_process可执行程序的位置在: ./frameworks/base/cmds/app_process/Android.mk,打开这个文件,内容如下:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= \ app_main.cppLOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libandroid_runtimeLOCAL_MODULE:= app_processinclude $(BUILD_EXECUTABLE)
从 LOCAL_SRC_FILES:= app_main.cpp 中,我们可以知道,其源码为:app_main.cpp
2、分析:app_main.cpp
打开app_main.cpp:./frameworks/base/cmds/app_process/,分析其结构。其中有两个最重要的部分,main函数,以及继承自AndroidRuntime的AppRuntime类。
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
其中的
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");
AppRuntime本身没有实现start方法,runtime.start继承了AndroidRuntime 的start。
frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const char* options){ /* start the virtual machine:启动虚拟机,后面分析 startVm()函数*/ JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env); /* * Register android functions. * 注册各种本地函数,具体可参看startReg()函数。 */ if (startReg(env) < 0) { LOGE("Unable to register all android natives\n"); return; } /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ //这里的className为runtime.start()传进来的:com.android.internal.os.ZygoteInit char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); //启动com.android.internal.os.ZygoteInit类中main函数 env->CallStaticVoidMethod(startClass, startMeth, strArray); }}
下面分析下:AndroidRuntime::startVm()
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv){ if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { LOGE("JNI_CreateJavaVM failed\n"); goto bail; }}
这里可以看到,JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) 方法创建了虚拟机!从上面的分析中,我们可以推出:
如何在C语言中运行(如果调用的话,可以简单的使用JNI即可)Java类!
(这部分,我想在以后的文章中具体讲解)
1、编写java程序
2、编写C 程序,其中在C中创建Java虚拟机,并调用创建好的虚拟机运行Java程序。
3、运行程序
更多相关文章
- Mms模块ConversationList流程分析
- Android应用开发攻略
- android things中与标准android系统不同的地方
- android static
- Android之数据存储笔记
- [Android] Linux下查看apk文件程序包名的办法
- 关于Android系统 和 Android应用程序
- Android(安卓)实现 Launcher
- Android(安卓)系统启动流程