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到底干了什么。

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

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android的NDK开发(1)————Android(安卓)JNI简介与调用流程
  4. Android在开机时自动启动一个应用程序
  5. Android(安卓)adb shell 启动java程序
  6. android下usb框架系列文章---(3)Storage框架整理
  7. Android(安卓)NDK打印log到logcat的方法
  8. 启动android默认浏览器
  9. Android(安卓)Service

随机推荐

  1. Android:网络:多线程断点下载
  2. RXjava+Retrofit二级购物车
  3. 兔子--多击事件
  4. android音乐播放器Media
  5. 自定义的跑马灯控件
  6. Android跟随手指运动的小球 …
  7. Mediastreamer2
  8. 滴滴插件化框架学习笔记之virtualapk-gra
  9. 自定义Android(安卓)ORM 框架greenDAO数
  10. Android(安卓)Annotations 仿微博Tabbar