android 源码分析2

Zygote是如何创建 Java世界的
frameworks\base\cmds\app_process\app_main.cpp

int main(int argc, const char* const argv[])
{
 /*
   Zygote进程由init通过fork而来,我们回顾一下init.rc中设置的启动参数:
    -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;
    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
     // 调用Appruntime的addVmArguments
    int i = runtime.addVmArguments(argc, argv);

    // Next arg is parent directory
    if (i < argc) {
      //设置runtime的mParentDir为/system/bin
        runtime.mParentDir = argv[i++];
    }

    // Next arg is startup classname or "--zygote"
    if (i < argc) {
        arg = argv[i++];
        if (0 == strcmp("--zygote", arg)) {
         //我们传入的参数满足if的条件,而且下面的startSystemServer的值为true
            bool startSystemServer = (i < argc) ? 
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            //设置本进程名为zygote
            set_process_name("zygote");
               //①调用runtime的start,注意第二个参数startSystemServer为trueruntime.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;
    }

}

Zygote中重要功能却是由AppRuntime的start来完成的
AppRuntime分析
AppRuntime类继承AndroidRuntime
class AppRuntime : public AndroidRuntime
AppRuntime重载了onStarted、onZygoteInit和onExit函数

AndroidRuntime.cpp
frameworks\base\core\jni\AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
//className的值是"com.android.internal.os.ZygoteInit"
 //startSystemServer的值是true
    LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");

    JNIEnv* env;
    JavaVMInitArgs initArgs;
    JavaVMOption opt;
    char propBuf[PROPERTY_VALUE_MAX];
    char stackTraceFileBuf[PROPERTY_VALUE_MAX];
    char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
    char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
    char* stackTraceFile = NULL;
    char* slashClassName = NULL;
    char* cp;
    bool checkJni = false;
    bool logStdio = false;
    enum { kEMDefault, kEMIntPortable, kEMIntFast } executionMode = kEMDefault;

    blockSigpipe();//处理SIGPIPE信号

    /* 
     * 'startSystemServer == true' means runtime is obslete and not run from 
     * init.rc anymore, so we print out the boot start event here.
     */
    if (startSystemServer) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 
                       ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }

    property_get("dalvik.vm.checkjni", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        checkJni = true;
    } else if (strcmp(propBuf, "false") != 0) {
        /* property is neither true nor false; fall back on kernel parameter */
        property_get("ro.kernel.android.checkjni", propBuf, "");
        if (propBuf[0] == '1') {
            checkJni = true;
        }
    }

    property_get("dalvik.vm.execution-mode", propBuf, "");
    if (strcmp(propBuf, "int:portable") == 0) {
        executionMode = kEMIntPortable;
    } else if (strcmp(propBuf, "int:fast") == 0) {
        executionMode = kEMIntFast;
    }

    property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");

    property_get("log.redirect-stdio", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        logStdio = true;
    }

    strcpy(enableAssertBuf, "-ea:");
    property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");

    strcpy(jniOptsBuf, "-Xjniopts:");
    property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* route exit() to our handler */
    opt.extraInfo = (void*) runtime_exit;
    opt.optionString = "exit";
    mOptions.add(opt);

    /* route fprintf() to our handler */
    opt.extraInfo = (void*) runtime_vfprintf;
    opt.optionString = "vfprintf";
    mOptions.add(opt);

    opt.extraInfo = NULL;

    /* enable verbose; standard options are { jni, gc, class } */
    //options[curOpt++].optionString = "-verbose:jni";
    opt.optionString = "-verbose:gc";
    mOptions.add(opt);
    //options[curOpt++].optionString = "-verbose:class";

#ifdef CUSTOM_RUNTIME_HEAP_MAX
#define __make_max_heap_opt(val) #val
#define _make_max_heap_opt(val) "-Xmx" __make_max_heap_opt(val)
    opt.optionString = _make_max_heap_opt(CUSTOM_RUNTIME_HEAP_MAX);
#undef __make_max_heap_opt
#undef _make_max_heap_opt
#else
    /* limit memory use to 16MB */
    opt.optionString = "-Xmx16m";
#endif
    mOptions.add(opt);

    /*
     * Enable or disable dexopt features, such as bytecode verification and
     * calculation of register maps for precise GC.
     */
    property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
    if (dexoptFlagsBuf[0] != '\0') {
        const char* opc;
        const char* val;

        opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
        if (opc != NULL) {
            switch (*(opc+2)) {
            case 'n':   val = "-Xverify:none";      break;
            case 'r':   val = "-Xverify:remote";    break;
            case 'a':   val = "-Xverify:all";       break;
            default:    val = NULL;                 break;
            }

            if (val != NULL) {
                opt.optionString = val;
                mOptions.add(opt);
            }
        }

        opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
        if (opc != NULL) {
            switch (*(opc+2)) {
            case 'n':   val = "-Xdexopt:none";      break;
            case 'v':   val = "-Xdexopt:verified";  break;
            case 'a':   val = "-Xdexopt:all";       break;
            default:    val = NULL;                 break;
            }

            if (val != NULL) {
                opt.optionString = val;
                mOptions.add(opt);
            }
        }

        opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
        if (opc != NULL) {
            opt.optionString = "-Xgenregmap";
            mOptions.add(opt);
        }
    }

    /* enable debugging; set suspend=y to pause during VM init */
#ifdef HAVE_ANDROID_OS
    /* use android ADB transport */
    opt.optionString =
        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
#else
    /* use TCP socket; address=0 means start at port 8000 and probe up */
    LOGI("Using TCP socket for JDWP\n");
    opt.optionString =
        "-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";
#endif
    mOptions.add(opt);

    char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];
    property_get("dalvik.vm.deadlock-predict", propBuf, "");
    if (strlen(propBuf) > 0) {
        strcpy(enableDPBuf, "-Xdeadlockpredict:");
        strcat(enableDPBuf, propBuf);
        opt.optionString = enableDPBuf;
        mOptions.add(opt);
    }

    LOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
    if (checkJni) {
        /* extended JNI checking */
        opt.optionString = "-Xcheck:jni";
        mOptions.add(opt);

        /* set a cap on JNI global references */
           //JNIcheck中的资源检查,系统中创建的Globalreference个数不能超过2000
        opt.optionString = "-Xjnigreflimit:2000";
        mOptions.add(opt);

        /* with -Xcheck:jni, this provides a JNI function call trace */
        //opt.optionString = "-verbose:jni";
        //mOptions.add(opt);
    }
    if (executionMode == kEMIntPortable) {
        opt.optionString = "-Xint:portable";
        mOptions.add(opt);
    } else if (executionMode == kEMIntFast) {
        opt.optionString = "-Xint:fast";
        mOptions.add(opt);
    }
    if (logStdio) {
        /* convert stdout/stderr to log messages */
        opt.optionString = "-Xlog-stdio";
        mOptions.add(opt);
    }

    if (enableAssertBuf[4] != '\0') {
        /* accept "all" to mean "all classes and packages" */
        if (strcmp(enableAssertBuf+4, "all") == 0)
            enableAssertBuf[3] = '\0';
        LOGI("Assertions enabled: '%s'\n", enableAssertBuf);
        opt.optionString = enableAssertBuf;
        mOptions.add(opt);
    } else {
        LOGV("Assertions disabled\n");
    }

    if (jniOptsBuf[10] != '\0') {
        LOGI("JNI options: '%s'\n", jniOptsBuf);
        opt.optionString = jniOptsBuf;
        mOptions.add(opt);
    }

    if (stackTraceFileBuf[0] != '\0') {
        static const char* stfOptName = "-Xstacktracefile:";

        stackTraceFile = (char*) malloc(strlen(stfOptName) +
            strlen(stackTraceFileBuf) +1);
        strcpy(stackTraceFile, stfOptName);
        strcat(stackTraceFile, stackTraceFileBuf);
        opt.optionString = stackTraceFile;
        mOptions.add(opt);
    }
    
    /* Set the properties for locale */
    {
        char langOption[sizeof("-Duser.language=") + 3];
        char regionOption[sizeof("-Duser.region=") + 3];
        strcpy(langOption, "-Duser.language=");
        strcpy(regionOption, "-Duser.region=");
        readLocale(langOption, regionOption);
        opt.extraInfo = NULL;
        opt.optionString = langOption;
        mOptions.add(opt);
        opt.optionString = regionOption;
        mOptions.add(opt);
    }

    /*
     * We don't have /tmp on the device, but we often have an SD card.  Apps
     * shouldn't use this, but some test suites might want to exercise it.
     */
    opt.optionString = "-Djava.io.tmpdir=/sdcard";
    mOptions.add(opt);

    initArgs.version = JNI_VERSION_1_4;
    initArgs.options = mOptions.editArray();
    initArgs.nOptions = mOptions.size();
    initArgs.ignoreUnrecognized = JNI_FALSE;

    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
      //① 创建虚拟机
    // 调用JNI_CreateJavaVM创建虚拟机,env返回当前线程的JNIEnv变量
    if (JNI_CreateJavaVM(&mJavaVM, &env, &initArgs) < 0) {
        LOGE("JNI_CreateJavaVM failed\n");
        goto bail;
    }

    /*
     * Register android functions.
     *  //②注册JNI函数
     */
    if (startReg(env) < 0) {
        LOGE("Unable to register all android natives\n");
        goto bail;
    }

    /*
     * We want to call main() with a String array with arguments in it.
     * At present we only have one argument, the class name.  Create an
     * array to hold it.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring startSystemServerStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
      //创建一个有两个元素的String数组,即Java代码 String strArray[] = new String[2]
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    //设置第一个元素为"com.android.internal.os.ZygoteInit"
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    //设置第二个元素为"true",注意这两个元素都是String类型,即字符串。
    startSystemServerStr = env->NewStringUTF(startSystemServer ? 
                                                 "true" : "false");
    env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    jclass startClass;
    jmethodID startMeth;

    slashClassName = strdup(className);
    /*
     将字符串“com.android.internal.os.ZygoteInit”中的“. ”换成“/”,
     这样就变成了“com/android/internal/os/ZygoteInit”,这个名字符合JNI规范,
     我们可将其简称为ZygoteInit类。
   */

    for (cp = slashClassName; *cp != '\0'; cp++)
        if (*cp == '.')
            *cp = '/';

    startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
      //找到ZygoteInit类的static main函数的jMethodId。
        startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
        /*
        ③通过JNI调用Java函数,注意调用的函数是main,所属的类是
          com.android.internal.os.ZygoteInit,传递的参数是
          “com.android.internal.os.ZygoteInit true”,
          调用ZygoteInit的main函数后,Zygote便进入了Java世界!
          也就是说,Zygote是开创Android系统中Java世界的盘古。
     */

            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }

    LOGD("Shutting down VM\n");
     //Zygote退出,在正常情况下,Zygote不需要退出。
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        LOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        LOGW("Warning: VM did not shut down cleanly\n");

bail:
    free(slashClassName);
    free(stackTraceFile);
}
virtual void onStarted()
    {
        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();
        }
    }

注册JNI函数——startReg

/*
 * Register android native functions with the VM.
 */
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     * //注意,设置Thread类的线程创建函数为javaCreateThreadEtc

     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    LOGD("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);
//注册jni函数,gRegJNI是一个全局数组。
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

们来看看register_jni_procs,

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {//仅仅是一个封装,调用数组元素的mProc函数
#ifndef NDEBUG
            LOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
            return -1;
        }
    }
    return 0;
}

分析CallStaticVoidMethod了。通过这个函数,我们将进入Android所精心打造的Java世界
Welcome to Java World
Java世界的入口
CallStaticVoidMethod最终将调用com.android.internal.os.ZygoteInit的main函数
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

public static void main(String argv[]) {
        try {
          //①注册Zygote用的socket
            registerZygoteSocket();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
                 //②预加载类和资源
            preloadClasses();
            preloadResources();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Do an initial gc to clean up after startup
              // 强制一次垃圾收集
            gc();

            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(
                        "ZygoteInit.main expects two arguments");
            }
//我们传入的参数满足if分支
            if (argv[1].equals("true")) {
            //③启动system_server进程
                startSystemServer();
            }

            Log.i(TAG, "Accepting command socket connections");
 // ZYGOTE_FORK_MODE被定义为false,所以满足else的条件
            if (ZYGOTE_FORK_MODE) {
                runForkMode();
            } else {
            //④zygote调用这个函数
                runSelectLoopMode();
            }
			//关闭socket
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
        //⑤很重要的caller run函数
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

1. 建立IPC通信服务端——registerZygoteSocket

Zygote以及系统中其他程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的Socket

  /**
     * Registers a server socket for zygote command connections
     *
     * @throws RuntimeException when open fails
     */
    private static void registerZygoteSocket() {
        if (sServerSocket == null) {
            int fileDesc;
            try {
              //从环境变量中获取Socket的fd
              //这个环境变量由execv传入。
                String env = System.getenv(ANDROID_SOCKET_ENV);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(
                        ANDROID_SOCKET_ENV + " unset or invalid", ex);
            }

            try {
             //创建服务端Socket,这个Socket将listen并accept Client
                sServerSocket = new LocalServerSocket(
                        createFileDescriptor(fileDesc));
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

registerZygoteSocket就是创建一个服务端的Socket

预加载类和资源

/**
     * Performs Zygote process initialization. Loads and initializes
     * commonly used classes.
     *
     * Most classes only cause a few hundred bytes to be allocated, but
     * a few will allocate a dozen Kbytes (in one case, 500+K).
     */
    private static void preloadClasses() {
        final VMRuntime runtime = VMRuntime.getRuntime();
         //预加载类的信息存储在PRELOADED_CLASSES变量中,它的值为"preloaded-classes"
        InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
                PRELOADED_CLASSES);
        if (is == null) {
            Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
        } else {
            Log.i(TAG, "Preloading classes...");
            long startTime = SystemClock.uptimeMillis();
            
            // Drop root perms while running static initializers.
            setEffectiveGroup(UNPRIVILEGED_GID);
            setEffectiveUser(UNPRIVILEGED_UID);

            // Alter the target heap utilization.  With explicit GCs this
            // is not likely to have any effect.
            float defaultUtilization = runtime.getTargetHeapUtilization();
            runtime.setTargetHeapUtilization(0.8f);

            // Start with a clean slate.
            runtime.gcSoftReferences();
            runtime.runFinalizationSync();
            Debug.startAllocCounting();

            try {
                BufferedReader br 
                    = new BufferedReader(new InputStreamReader(is), 256);
    //读取文件的每一行,忽略#开头的注释行
                int count = 0;
                String line;
                String missingClasses = null;
                while ((line = br.readLine()) != null) {
                    // Skip comments and blank lines.
                    line = line.trim();
                    if (line.startsWith("#") || line.equals("")) {
                        continue;
                    }

                    try {
                        if (Config.LOGV) {
                            Log.v(TAG, "Preloading " + line + "...");
                        }
                          //通过Java反射来加载类,line中存储的是预加载的类名
                        Class.forName(line);
                        if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
                            if (Config.LOGV) {
                                Log.v(TAG,
                                    " GC at " + Debug.getGlobalAllocSize());
                            }
                            runtime.gcSoftReferences();
                            runtime.runFinalizationSync();
                            Debug.resetGlobalAllocSize();
                        }
                        count++;
                    } catch (ClassNotFoundException e) {
                        Log.e(TAG, "Class not found for preloading: " + line);
                        if (missingClasses == null) {
                            missingClasses = line;
                        } else {
                            missingClasses += " " + line;
                        }
                    } catch (Throwable t) {
                        Log.e(TAG, "Error preloading " + line + ".", t);
                        if (t instanceof Error) {
                            throw (Error) t;
                        }
                        if (t instanceof RuntimeException) {
                            throw (RuntimeException) t;
                        }
                        throw new RuntimeException(t);
                    }
                }

                if (missingClasses != null &&
                        "1".equals(SystemProperties.get("persist.service.adb.enable"))) {
                    throw new IllegalStateException(
                            "Missing class(es) for preloading, update preloaded-classes ["
                            + missingClasses + "]");
                }

                Log.i(TAG, "...preloaded " + count + " classes in "
                        + (SystemClock.uptimeMillis()-startTime) + "ms.");
            } catch (IOException e) {
                Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
            } finally {
                // Restore default.
                runtime.setTargetHeapUtilization(defaultUtilization);

                Debug.stopAllocCounting();

                // Bring back root. We'll need it later.
                setEffectiveUser(ROOT_UID);
                setEffectiveGroup(ROOT_GID);
            }
        }
    }

用coolfind在framework中搜索名为“preloaded-classes”的文件,最后会在framework/base目录下找到。它是一个文本文件,内容如下:
frameworks\base\preloaded-classes

# Classes which are preloaded by com.android.internal.os.ZygoteInit.
# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.
# MIN_LOAD_TIME_MICROS=1250 //超时控制
SQLite.Blob
SQLite.Database
SQLite.FunctionContext
SQLite.Stmt
SQLite.Vm
android.R$styleable
android.accounts.IAccountsService$Stub
android.app.Activity
android.app.ActivityGroup
android.app.ActivityManager
android.app.ActivityManager$MemoryInfo
android.app.ActivityManagerNative
android.app.ActivityManagerProxy
android.app.ActivityThread
android.app.ActivityThread$ApplicationThread
android.app.ActivityThread$H
android.app.AlertDialog
android.app.Application
android.app.ApplicationContext
android.app.ApplicationContext$ApplicationContentResolver
android.app.ApplicationContext$ApplicationPackageManager
android.app.ApplicationContext$WallpaperCallback
android.app.ApplicationThreadNative
android.app.DatePickerDialog
android.app.Dialog
android.app.ExpandableListActivity
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
android.app.IAlarmManager$Stub
android.app.INotificationManager$Stub
android.app.ISearchManager$Stub
android.app.ISearchManagerCallback$Stub
android.app.IStatusBar$Stub
android.app.ITransientNotification$Stub
android.app.IWallpaperService$Stub
android.app.IWallpaperServiceCallback$Stub
android.app.Instrumentation
android.app.IntentService
android.app.ListActivity
android.app.LocalActivityManager
android.app.Notification
android.app.PendingIntent
android.app.ProgressDialog
android.app.ResultInfo
android.app.SearchManager$SearchManagerCallback
android.app.Service
android.app.StatusBarManager
android.app.TabActivity
android.app.TimePickerDialog
android.appwidget.AppWidgetHost
android.appwidget.AppWidgetHostView
android.appwidget.AppWidgetManager
android.appwidget.AppWidgetProvider
android.appwidget.AppWidgetProviderInfo
android.backup.BackupDataInput
android.backup.BackupDataInput$EntityHeader
android.backup.BackupDataOutput
android.backup.BackupHelperDispatcher
android.backup.BackupHelperDispatcher$Header
android.backup.FileBackupHelperBase
android.bluetooth.BluetoothAudioGateway
android.bluetooth.BluetoothDevice
android.bluetooth.Database
android.bluetooth.HeadsetBase
android.bluetooth.IBluetoothA2dp
android.bluetooth.IBluetoothA2dp$Stub
android.bluetooth.IBluetoothDevice
android.bluetooth.IBluetoothDevice$Stub
android.bluetooth.IBluetoothDevice$Stub$Proxy
android.bluetooth.RfcommSocket
android.bluetooth.ScoSocket
android.content.AbstractSyncableContentProvider
android.content.AbstractTableMerger
android.content.ComponentName
android.content.ContentProvider$Transport
android.content.ContentResolver
android.content.ContentResolver$CursorWrapperInner
android.content.ContentValues
android.content.Context
android.content.ContextWrapper
android.content.DialogInterface$OnMultiChoiceClickListener
android.content.IContentService$Stub
android.content.ISyncAdapter$Stub
android.content.Intent
android.content.Intent$ShortcutIconResource
android.content.IntentFilter
android.content.SyncAdapter$Transport
android.content.SyncResult
android.content.SyncStateContentProviderHelper
android.content.SyncStats
android.content.SyncableContentProvider
android.content.TempProviderSyncAdapter
android.content.UriMatcher
android.content.pm.ActivityInfo
android.content.pm.ApplicationInfo
android.content.pm.ConfigurationInfo
android.content.pm.IPackageDataObserver$Stub
android.content.pm.IPackageDeleteObserver$Stub
android.content.pm.IPackageManager$Stub
android.content.pm.IPackageManager$Stub$Proxy
android.content.pm.IPackageStatsObserver$Stub
android.content.pm.InstrumentationInfo
android.content.pm.PackageInfo
android.content.pm.PackageManager
android.content.pm.PackageStats
android.content.pm.PathPermission
android.content.pm.PermissionInfo
android.content.pm.ResolveInfo
android.content.pm.Signature
android.content.res.AssetFileDescriptor
android.content.res.AssetFileDescriptor$1
android.content.res.AssetManager
android.content.res.AssetManager$AssetInputStream
android.content.res.ColorStateList
android.content.res.ColorStateList$1
android.content.res.CompatibilityInfo
android.content.res.CompatibilityInfo$1
android.content.res.Configuration
android.content.res.Configuration$1
android.content.res.Resources
android.content.res.Resources$1
android.content.res.StringBlock
android.content.res.TypedArray
android.content.res.XmlBlock
android.content.res.XmlBlock$Parser
android.content.res.XmlResourceParser
android.database.AbstractCursor
android.database.AbstractWindowedCursor
android.database.BulkCursorToCursorAdaptor
android.database.CharArrayBuffer
android.database.CursorJoiner$Result
android.database.CursorToBulkCursorAdaptor
android.database.CursorWindow
android.database.CursorWindow$1
android.database.CursorWrapper
android.database.DatabaseUtils
android.database.MatrixCursor
android.database.MergeCursor
android.database.sqlite.SQLiteClosable
android.database.sqlite.SQLiteCursor
android.database.sqlite.SQLiteDatabase
android.database.sqlite.SQLiteDatabase$ConflictAlgorithm
android.database.sqlite.SQLiteDebug
android.database.sqlite.SQLiteDebug$PagerStats
android.database.sqlite.SQLiteDirectCursorDriver
android.database.sqlite.SQLiteProgram
android.database.sqlite.SQLiteQuery
android.database.sqlite.SQLiteQueryBuilder
android.database.sqlite.SQLiteStatement
android.ddm.DdmHandleHeap
android.ddm.DdmHandleHello
android.ddm.DdmHandleNativeHeap
android.ddm.DdmHandleProfiling
android.ddm.DdmHandleThread
android.ddm.DdmRegister
android.debug.JNITest
android.emoji.EmojiFactory
android.graphics.AvoidXfermode
android.graphics.Bitmap
android.graphics.Bitmap$1
android.graphics.Bitmap$CompressFormat
android.graphics.Bitmap$Config
android.graphics.BitmapFactory
android.graphics.BitmapFactory$Options
android.graphics.BitmapShader
android.graphics.BlurMaskFilter
android.graphics.Camera
android.graphics.Canvas
android.graphics.Color
android.graphics.ColorFilter
android.graphics.ColorMatrixColorFilter
android.graphics.ComposePathEffect
android.graphics.ComposeShader
android.graphics.CornerPathEffect
android.graphics.DashPathEffect
android.graphics.DiscretePathEffect
android.graphics.DrawFilter
android.graphics.EmbossMaskFilter
android.graphics.Interpolator
android.graphics.LayerRasterizer
android.graphics.LightingColorFilter
android.graphics.LinearGradient
android.graphics.MaskFilter
android.graphics.Matrix
android.graphics.Movie
android.graphics.NinePatch
android.graphics.Paint
android.graphics.Paint$Align
android.graphics.Paint$Cap
android.graphics.Paint$FontMetrics
android.graphics.Paint$FontMetricsInt
android.graphics.Paint$Join
android.graphics.Paint$Style
android.graphics.PaintFlagsDrawFilter
android.graphics.Path
android.graphics.Path$FillType
android.graphics.PathDashPathEffect
android.graphics.PathEffect
android.graphics.PathMeasure
android.graphics.Picture
android.graphics.PixelFormat
android.graphics.PixelXorXfermode
android.graphics.Point
android.graphics.PointF
android.graphics.PorterDuff$Mode
android.graphics.PorterDuffColorFilter
android.graphics.PorterDuffXfermode
android.graphics.RadialGradient
android.graphics.Rasterizer
android.graphics.Rect
android.graphics.Rect$1
android.graphics.RectF
android.graphics.RectF$1
android.graphics.Region
android.graphics.Region$1
android.graphics.Region$Op
android.graphics.RegionIterator
android.graphics.Shader
android.graphics.Shader$TileMode
android.graphics.SumPathEffect
android.graphics.SweepGradient
android.graphics.Typeface
android.graphics.Xfermode
android.graphics.drawable.Animatable
android.graphics.drawable.AnimatedRotateDrawable
android.graphics.drawable.AnimatedRotateDrawable$AnimatedRotateState
android.graphics.drawable.AnimationDrawable
android.graphics.drawable.AnimationDrawable$AnimationState
android.graphics.drawable.BitmapDrawable
android.graphics.drawable.BitmapDrawable$BitmapState
android.graphics.drawable.ClipDrawable
android.graphics.drawable.ClipDrawable$ClipState
android.graphics.drawable.ColorDrawable
android.graphics.drawable.ColorDrawable$ColorState
android.graphics.drawable.Drawable
android.graphics.drawable.Drawable$Callback
android.graphics.drawable.Drawable$ConstantState
android.graphics.drawable.DrawableContainer
android.graphics.drawable.DrawableContainer$DrawableContainerState
android.graphics.drawable.GradientDrawable
android.graphics.drawable.GradientDrawable$GradientState
android.graphics.drawable.GradientDrawable$Orientation
android.graphics.drawable.LayerDrawable
android.graphics.drawable.LayerDrawable$ChildDrawable
android.graphics.drawable.LayerDrawable$LayerState
android.graphics.drawable.NinePatchDrawable
android.graphics.drawable.NinePatchDrawable$NinePatchState
android.graphics.drawable.PaintDrawable
android.graphics.drawable.RotateDrawable
android.graphics.drawable.ShapeDrawable
android.graphics.drawable.StateListDrawable
android.graphics.drawable.StateListDrawable$StateListState
android.graphics.drawable.TransitionDrawable
android.graphics.drawable.TransitionDrawable$TransitionState
android.graphics.drawable.shapes.RoundRectShape
android.hardware.Camera
android.hardware.ISensorService$Stub
android.hardware.SensorManager
android.inputmethodservice.AbstractInputMethodService
android.inputmethodservice.AbstractInputMethodService$AbstractInputMethodSessionImpl
android.inputmethodservice.ExtractButton
android.inputmethodservice.ExtractEditText
android.inputmethodservice.IInputMethodSessionWrapper
android.inputmethodservice.IInputMethodSessionWrapper$InputMethodEventCallbackWrapper
android.inputmethodservice.IInputMethodWrapper
android.inputmethodservice.InputMethodService
android.inputmethodservice.Keyboard
android.inputmethodservice.Keyboard$Key
android.inputmethodservice.KeyboardView
android.inputmethodservice.KeyboardView$2
android.location.Address
android.location.Criteria
android.location.ILocationManager$Stub
android.location.ILocationManager$Stub$Proxy
android.location.ILocationProvider
android.location.ILocationProvider$Stub
android.location.Location
android.location.LocationManager
android.location.LocationManager$ListenerTransport
android.location.LocationManager$LpPowerComparator
android.media.AudioFormat
android.media.AudioManager
android.media.AudioRecord
android.media.AudioSystem
android.media.AudioTrack
android.media.ExifInterface
android.media.FaceDetector
android.media.FaceDetector$Face
android.media.IAudioService$Stub
android.media.IAudioService$Stub$Proxy
android.media.JetPlayer
android.media.MediaMetadataRetriever
android.media.MediaPlayer
android.media.MediaRecorder
android.media.MediaScanner
android.media.MediaScanner$MyMediaScannerClient
android.media.Ringtone
android.media.RingtoneManager
android.media.ToneGenerator
android.net.ConnectivityManager
android.net.Credentials
android.net.DhcpInfo
android.net.DhcpInfo$1
android.net.IConnectivityManager$Stub
android.net.LocalServerSocket
android.net.LocalSocket
android.net.LocalSocketAddress$Namespace
android.net.LocalSocketImpl
android.net.LocalSocketImpl$SocketInputStream
android.net.LocalSocketImpl$SocketOutputStream
android.net.NetworkConnectivityListener
android.net.NetworkInfo
android.net.NetworkInfo$DetailedState
android.net.NetworkUtils
android.net.Uri
android.net.Uri$HierarchicalUri
android.net.Uri$OpaqueUri
android.net.Uri$Part
android.net.Uri$StringUri
android.net.WebAddress
android.net.http.AndroidHttpClient
android.net.http.AndroidHttpClient$2
android.net.http.CertificateChainValidator
android.net.http.Connection
android.net.http.DomainNameChecker
android.net.http.EventHandler
android.net.http.Headers
android.net.http.HttpsConnection
android.net.http.Request
android.net.http.RequestQueue
android.net.http.SslCertificate
android.net.vpn.IVpnService$Stub
android.net.vpn.PptpProfile
android.net.vpn.VpnManager
android.net.vpn.VpnProfile
android.net.vpn.VpnState
android.net.vpn.VpnType
android.net.wifi.IWifiManager$Stub
android.net.wifi.IWifiManager$Stub$Proxy
android.net.wifi.WifiManager
android.net.wifi.WifiNative
android.opengl.GLES10
android.opengl.GLES10Ext
android.opengl.GLES11
android.opengl.GLES11Ext
android.opengl.GLU
android.opengl.GLUtils
android.opengl.Matrix
android.opengl.Visibility
android.os.Base64Utils
android.os.Binder
android.os.BinderProxy
android.os.Build
android.os.Build$VERSION
android.os.Bundle
android.os.DeadObjectException
android.os.Debug
android.os.Debug$MemoryInfo
android.os.Environment
android.os.Exec
android.os.FileObserver$ObserverThread
android.os.FileUtils
android.os.FileUtils$FileStatus
android.os.Handler
android.os.Hardware
android.os.IBinder
android.os.ICheckinService$Stub
android.os.IHardwareService$Stub
android.os.IInterface
android.os.IMountService$Stub
android.os.IParentalControlCallback$Stub
android.os.IPowerManager$Stub
android.os.Looper
android.os.MemoryFile
android.os.Message
android.os.NetStat
android.os.Parcel
android.os.Parcel$1
android.os.ParcelFileDescriptor
android.os.ParcelFileDescriptor$1
android.os.Parcelable
android.os.Parcelable$Creator
android.os.PatternMatcher
android.os.Power
android.os.Process
android.os.ResultReceiver
android.os.StatFs
android.os.SystemClock
android.os.SystemProperties
android.os.UEventObserver
android.pim.EventRecurrence
android.preference.CheckBoxPreference
android.preference.CheckBoxPreference$SavedState
android.preference.DialogPreference
android.preference.EditTextPreference
android.preference.ListPreference
android.preference.ListPreference$SavedState
android.preference.Preference
android.preference.PreferenceActivity
android.preference.PreferenceGroup
android.preference.PreferenceGroupAdapter
android.preference.PreferenceInflater
android.preference.PreferenceManager
android.preference.PreferenceScreen
android.preference.RingtonePreference
android.preference.VolumePreference
android.preference.VolumePreference$SeekBarVolumizer
android.provider.Browser
android.provider.Calendar$Attendees
android.provider.Calendar$BusyBits
android.provider.Calendar$CalendarAlerts
android.provider.Calendar$Calendars
android.provider.Calendar$Events
android.provider.Calendar$Instances
android.provider.CallLog$Calls
android.provider.Checkin$Events$Tag
android.provider.Checkin$Properties
android.provider.Checkin$Properties$Tag
android.provider.Checkin$Stats$Tag
android.provider.Contacts
android.provider.Contacts$ContactMethods
android.provider.Contacts$People
android.provider.Contacts$Phones
android.provider.Contacts$Presence
android.provider.Contacts$Settings
android.provider.Downloads
android.provider.Gmail
android.provider.Gmail$AttachmentOrigin
android.provider.Gmail$AttachmentRendition
android.provider.Gmail$ConversationCursor
android.provider.Gmail$CursorStatus
android.provider.Gmail$LabelMap
android.provider.Gmail$MessageCursor
android.provider.Gmail$PersonalLevel
android.provider.Gmail$Settings
android.provider.Im$Account
android.provider.Im$Avatars
android.provider.Im$Chats
android.provider.Im$Contacts
android.provider.Im$LastRmqId
android.provider.Im$Messages
android.provider.Im$OutgoingRmq
android.provider.Im$Presence
android.provider.Im$Provider
android.provider.Im$ProviderSettings
android.provider.MediaStore
android.provider.MediaStore$Audio$Albums
android.provider.MediaStore$Audio$Artists
android.provider.MediaStore$Audio$Artists$Albums
android.provider.MediaStore$Audio$Media
android.provider.MediaStore$Audio$Playlists
android.provider.MediaStore$Images$Media
android.provider.MediaStore$Images$Thumbnails
android.provider.SearchRecentSuggestions
android.provider.Settings$Gservices
android.provider.Settings$Secure
android.provider.Settings$System
android.provider.SubscribedFeeds$Feeds
android.provider.Telephony$Carriers
android.provider.Telephony$Mms
android.provider.Telephony$MmsSms
android.provider.Telephony$MmsSms$PendingMessages
android.provider.Telephony$Sms
android.provider.Telephony$Sms$Conversations
android.provider.Telephony$Threads
android.provider.UserDictionary
android.provider.UserDictionary$Words
android.sax.RootElement
android.sax.RootElement$Handler
android.security.Keystore
android.security.Keystore$FileKeystore
android.security.Md5MessageDigest
android.security.MessageDigest
android.security.ServiceCommand
android.security.Sha1MessageDigest
android.server.BluetoothA2dpService
android.server.BluetoothDeviceService
android.server.BluetoothEventLoop
android.server.data.BuildData
android.server.data.CrashData
android.server.data.ThrowableData
android.server.search.SearchableInfo
android.server.search.Searchables
android.speech.IRecognitionListener$Stub
android.speech.IRecognitionService$Stub
android.speech.RecognitionResult
android.speech.RecognitionServiceUtil
android.speech.srec.MicrophoneInputStream
android.speech.srec.Recognizer
android.speech.tts.ITts$Stub
android.speech.tts.ITts$Stub$Proxy
android.speech.tts.TextToSpeech
android.telephony.PhoneNumberUtils
android.telephony.PhoneStateListener$1
android.telephony.ServiceState
android.telephony.SignalStrength
android.telephony.SmsMessage
android.telephony.TelephonyManager
android.text.AndroidCharacter
android.text.Annotation
android.text.AutoText
android.text.BoringLayout
android.text.DynamicLayout
android.text.Html
android.text.Html$HtmlParser
android.text.HtmlToSpannedConverter
android.text.IClipboard$Stub
android.text.Layout
android.text.Selection
android.text.SpannableStringBuilder
android.text.SpannedString
android.text.StaticLayout
android.text.TextUtils
android.text.format.DateUtils
android.text.format.Formatter
android.text.format.Time
android.text.method.ArrowKeyMovementMethod
android.text.method.BaseKeyListener
android.text.method.DialerKeyListener
android.text.method.DigitsKeyListener
android.text.method.LinkMovementMethod
android.text.method.MetaKeyKeyListener
android.text.method.QwertyKeyListener
android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
android.text.method.SingleLineTransformationMethod
android.text.method.TextKeyListener
android.text.style.BulletSpan
android.text.style.ImageSpan
android.text.style.MetricAffectingSpan
android.text.style.StyleSpan
android.text.style.TextAppearanceSpan
android.text.style.URLSpan
android.text.util.Linkify
android.text.util.Regex
android.text.util.Rfc822Validator
android.util.AttributeSet
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
android.util.EventLog$List
android.util.FloatMath
android.util.Log
android.util.LongSparseArray
android.util.SparseArray
android.util.StateSet
android.util.TypedValue
android.util.Xml
android.util.Xml$Encoding
android.view.AbsSavedState
android.view.ContextThemeWrapper
android.view.Display
android.view.FocusFinder
android.view.GestureDetector
android.view.GestureDetector$SimpleOnGestureListener
android.view.IRotationWatcher$Stub
android.view.IWindowManager$Stub
android.view.IWindowManager$Stub$Proxy
android.view.IWindowSession$Stub
android.view.KeyCharacterMap
android.view.KeyCharacterMap$KeyData
android.view.KeyEvent
android.view.LayoutInflater
android.view.MenuInflater$MenuState
android.view.MotionEvent
android.view.Surface
android.view.Surface$1
android.view.SurfaceSession
android.view.SurfaceView
android.view.VelocityTracker
android.view.View
android.view.View$AttachInfo$Callbacks
android.view.View$AttachInfo$InvalidateInfo
android.view.View$BaseSavedState
android.view.ViewGroup
android.view.ViewParent
android.view.ViewRoot
android.view.ViewStub
android.view.Window
android.view.WindowManager$LayoutParams
android.view.WindowManagerImpl
android.view.accessibility.AccessibilityEvent
android.view.accessibility.AccessibilityEvent$1
android.view.animation.Animation
android.view.animation.AnimationSet
android.view.inputmethod.BaseInputConnection
android.view.inputmethod.CompletionInfo
android.view.inputmethod.EditorInfo
android.view.inputmethod.ExtractedText
android.view.inputmethod.InputMethodInfo
android.view.inputmethod.InputMethodManager
android.view.inputmethod.InputMethodManager$1
android.webkit.BrowserFrame
android.webkit.CacheLoader
android.webkit.CacheManager
android.webkit.CallbackProxy
android.webkit.CallbackProxy$ResultTransport
android.webkit.CookieManager
android.webkit.CookieSyncManager
android.webkit.DataLoader
android.webkit.GearsPermissionsManager
android.webkit.HttpDateTime
android.webkit.JWebCoreJavaBridge
android.webkit.LoadListener
android.webkit.MimeTypeMap
android.webkit.TextDialog
android.webkit.URLUtil
android.webkit.WebIconDatabase$IconListener
android.webkit.WebSettings
android.webkit.WebSettings$TextSize
android.webkit.WebView
android.webkit.WebView$HitTestResult
android.webkit.WebViewCore
android.webkit.WebViewDatabase
android.webkit.gears.ApacheHttpRequestAndroid
android.webkit.gears.ApacheHttpRequestAndroid$Buffer
android.webkit.gears.NativeDialog
android.widget.AbsListView
android.widget.AbsListView$3
android.widget.AbsListView$PerformClick
android.widget.AbsListView$SavedState
android.widget.AbsSeekBar
android.widget.AbsSpinner
android.widget.AbsSpinner$SavedState
android.widget.AbsoluteLayout
android.widget.AdapterView
android.widget.AnalogClock
android.widget.AppSecurityPermissions
android.widget.AppSecurityPermissions$State
android.widget.ArrayAdapter
android.widget.AutoCompleteTextView
android.widget.AutoCompleteTextView$DropDownListView
android.widget.BaseAdapter
android.widget.BaseExpandableListAdapter
android.widget.CheckBox
android.widget.CheckedTextView
android.widget.Chronometer
android.widget.CompoundButton
android.widget.CompoundButton$SavedState
android.widget.CursorAdapter
android.widget.CursorTreeAdapter
android.widget.DatePicker
android.widget.EditText
android.widget.ExpandableListConnector
android.widget.ExpandableListConnector$GroupMetadata
android.widget.ExpandableListView
android.widget.FastScroller
android.widget.FrameLayout
android.widget.Gallery
android.widget.GridView
android.widget.HeaderViewListAdapter
android.widget.ImageView
android.widget.ImageView$ScaleType
android.widget.LinearLayout
android.widget.ListView
android.widget.ListView$SavedState
android.widget.MediaController
android.widget.MultiAutoCompleteTextView
android.widget.PopupWindow
android.widget.PopupWindow$PopupViewContainer
android.widget.ProgressBar
android.widget.ProgressBar$SavedState
android.widget.RadioButton
android.widget.RadioGroup
android.widget.RatingBar
android.widget.RelativeLayout
android.widget.RelativeLayout$DependencyGraph$Node
android.widget.RemoteViews
android.widget.ResourceCursorAdapter
android.widget.ResourceCursorTreeAdapter
android.widget.ScrollBarDrawable
android.widget.ScrollView
android.widget.SeekBar
android.widget.SimpleAdapter
android.widget.SimpleCursorAdapter
android.widget.SimpleCursorTreeAdapter
android.widget.SlidingDrawer
android.widget.Spinner
android.widget.Spinner$DropDownAdapter
android.widget.TabHost
android.widget.TabWidget
android.widget.TableLayout
android.widget.TableRow
android.widget.TextView
android.widget.TextView$BufferType
android.widget.TextView$CommitSelectionReceiver
android.widget.TextView$SavedState
android.widget.TimePicker
android.widget.TimePicker$SavedState
android.widget.Toast
android.widget.Toast$TN
android.widget.TwoLineListItem
android.widget.VideoView
android.widget.ViewAnimator
android.widget.ViewSwitcher
android.widget.ZoomButton
android.widget.ZoomButtonsController
android.widget.ZoomControls
com.android.internal.R$drawable
com.android.internal.R$styleable
com.android.internal.app.AlertActivity
com.android.internal.app.AlertController
com.android.internal.app.AlertController$AlertParams
com.android.internal.app.AlertController$AlertParams$1
com.android.internal.app.AlertController$RecycleListView
com.android.internal.app.ChooserActivity
com.android.internal.app.ResolverActivity
com.android.internal.app.ResolverActivity$ResolveListAdapter
com.android.internal.app.RingtonePickerActivity
com.android.internal.appwidget.IAppWidgetHost$Stub
com.android.internal.appwidget.IAppWidgetService$Stub
com.android.internal.database.ArrayListCursor
com.android.internal.database.SortCursor
com.android.internal.database.SortCursor$1
com.android.internal.graphics.NativeUtils
com.android.internal.location.DummyLocationProvider
com.android.internal.location.GpsLocationProvider
com.android.internal.logging.AndroidHandler
com.android.internal.os.AndroidPrintStream
com.android.internal.os.BinderInternal
com.android.internal.os.BinderInternal$GcWatcher
com.android.internal.os.LoggingPrintStream
com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit$1
com.android.internal.os.ZygoteConnection
com.android.internal.os.ZygoteConnection$Arguments
com.android.internal.os.ZygoteInit
com.android.internal.policy.PolicyManager
com.android.internal.policy.impl.PhoneLayoutInflater
com.android.internal.policy.impl.PhoneWindow
com.android.internal.policy.impl.PhoneWindow$DecorView
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
com.android.internal.policy.impl.PhoneWindowManager
com.android.internal.policy.impl.Policy
com.android.internal.telephony.GsmAlphabet
com.android.internal.telephony.IPhoneStateListener$Stub
com.android.internal.telephony.IPhoneSubInfo$Stub
com.android.internal.telephony.ITelephony$Stub
com.android.internal.telephony.ITelephony$Stub$Proxy
com.android.internal.telephony.ITelephonyRegistry$Stub
com.android.internal.telephony.IccCard$State
com.android.internal.telephony.Phone$State
com.android.internal.telephony.PhoneStateIntentReceiver
com.android.internal.telephony.SmsMessageBase
com.android.internal.telephony.gsm.GsmSmsAddress
com.android.internal.telephony.gsm.SmsMessage
com.android.internal.telephony.gsm.SmsMessage$SubmitPdu
com.android.internal.util.ArrayUtils
com.android.internal.util.FastXmlSerializer
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputContext$Stub
com.android.internal.view.IInputMethod$Stub
com.android.internal.view.IInputMethodManager$Stub
com.android.internal.view.InputConnectionWrapper$InputContextCallback
com.android.internal.view.menu.ExpandedMenuView
com.android.internal.view.menu.IconMenuItemView
com.android.internal.view.menu.IconMenuView
com.android.internal.view.menu.IconMenuView$SavedState
com.android.internal.view.menu.ListMenuItemView
com.android.internal.view.menu.MenuBuilder
com.android.internal.view.menu.MenuItemImpl
com.android.internal.view.menu.SubMenuBuilder
com.android.internal.widget.LockPatternUtils
com.android.internal.widget.NumberPicker
com.android.internal.widget.NumberPickerButton
com.android.internal.widget.Smileys
com.google.android.gdata.client.AndroidGDataClient
com.google.android.gdata.client.AndroidXmlParserFactory
com.google.android.gles_jni.EGLImpl
com.google.android.gles_jni.GLImpl
com.google.android.mms.pdu.PduPersister
com.google.android.mms.util.PduCache
com.google.android.net.GoogleHttpClient
com.google.android.net.NetworkStatsEntity
com.google.android.net.UrlRules
com.google.android.net.UrlRules$Rule
com.google.common.Config
com.google.common.Log
com.google.common.android.AndroidConfig
com.google.common.async.AsyncHttpRequestFactory$AsyncHttpRequestImpl
com.google.common.graphics.android.AndroidGraphics
com.google.common.io.BaseHttpConnectionFactory
com.google.common.io.IoUtil
com.google.common.io.android.AndroidHttpClient
com.google.common.io.android.AndroidHttpConnectionFactory
com.google.common.io.android.AndroidPersistentStore
com.google.common.io.protocol.ProtoBuf
com.google.common.io.protocol.ProtoBufType
com.google.common.util.text.TextUtil
com.google.masf.BlockingByteQueue
com.google.masf.MobileServiceMux
com.google.masf.protocol.PlainRequest
com.google.masf.services.EventLogService
com.google.masf.services.LogserviceMessageTypes
com.google.masf.services.resume.WindowResumeService
com.google.wireless.gdata.calendar.client.CalendarClient
com.google.wireless.gdata.client.GDataServiceClient
com.google.wireless.gdata.contacts.client.ContactsClient
com.google.wireless.gdata.contacts.parser.xml.XmlContactsGDataParserFactory
com.ibm.icu4jni.charset.CharsetDecoderICU
com.ibm.icu4jni.charset.CharsetEncoderICU
com.ibm.icu4jni.charset.CharsetICU
com.ibm.icu4jni.charset.CharsetProviderICU
com.ibm.icu4jni.charset.NativeConverter
com.ibm.icu4jni.common.ErrorCode
com.ibm.icu4jni.lang.UCharacter
com.ibm.icu4jni.regex.NativeRegEx
com.ibm.icu4jni.text.DecimalFormat
com.ibm.icu4jni.text.NativeBreakIterator
com.ibm.icu4jni.text.NativeCollation
com.ibm.icu4jni.text.NativeDecimalFormat
com.ibm.icu4jni.text.NativeDecimalFormat$UNumberFormatAttribute
com.ibm.icu4jni.text.NativeDecimalFormat$UNumberFormatSymbol
com.ibm.icu4jni.text.RuleBasedNumberFormat
com.ibm.icu4jni.util.Resources
dalvik.system.NativeStart
dalvik.system.PathClassLoader
dalvik.system.TouchDex
dalvik.system.VMDebug
dalvik.system.VMRuntime
dalvik.system.VMStack
dalvik.system.Zygote
java.beans.PropertyChangeEvent
java.beans.PropertyChangeSupport
java.io.BufferedInputStream
java.io.BufferedReader
java.io.Closeable
java.io.DataInput
java.io.DataOutput
java.io.DataOutputStream
java.io.EmulatedFieldsForDumping
java.io.EmulatedFieldsForLoading
java.io.File
java.io.FileDescriptor
java.io.FileInputStream
java.io.FileInputStream$RepositioningLock
java.io.FileOutputStream
java.io.FilterOutputStream
java.io.Flushable
java.io.InputStream
java.io.InputStreamReader
java.io.ObjectInput
java.io.ObjectInputStream
java.io.ObjectOutput
java.io.ObjectOutputStream
java.io.ObjectStreamClass
java.io.ObjectStreamConstants
java.io.ObjectStreamField
java.io.OutputStream
java.io.PrintStream
java.io.PrintWriter
java.io.PushbackReader
java.io.RandomAccessFile
java.io.Reader
java.io.Serializable
java.io.StringWriter
java.lang.AbstractStringBuilder
java.lang.Appendable
java.lang.ArrayIndexOutOfBoundsException
java.lang.Boolean
java.lang.BootClassLoader
java.lang.Byte
java.lang.CharSequence
java.lang.Character
java.lang.Character$valueOfCache
java.lang.Class
java.lang.ClassCache
java.lang.ClassCache$EnumComparator
java.lang.ClassLoader
java.lang.ClassLoader$SystemClassLoader
java.lang.Cloneable
java.lang.Comparable
java.lang.Double
java.lang.Enum
java.lang.Error
java.lang.Exception
java.lang.Float
java.lang.IllegalArgumentException
java.lang.Integer
java.lang.Integer$valueOfCache
java.lang.InternalError
java.lang.InterruptedException
java.lang.Iterable
java.lang.LangAccessImpl
java.lang.LinkageError
java.lang.Long
java.lang.Long$valueOfCache
java.lang.Math
java.lang.NoClassDefFoundError
java.lang.Number
java.lang.NumberFormatException
java.lang.Object
java.lang.OutOfMemoryError
java.lang.Readable
java.lang.Runnable
java.lang.Runtime
java.lang.RuntimeException
java.lang.RuntimePermission
java.lang.SecurityException
java.lang.Short
java.lang.Short$valueOfCache
java.lang.StackOverflowError
java.lang.StackTraceElement
java.lang.StrictMath
java.lang.String
java.lang.String$CaseInsensitiveComparator
java.lang.StringBuffer
java.lang.StringBuilder
java.lang.System
java.lang.SystemProperties
java.lang.Thread
java.lang.Thread$State
java.lang.Thread$UncaughtExceptionHandler
java.lang.ThreadGroup
java.lang.ThreadGroup$ChildrenGroupsLock
java.lang.ThreadGroup$ChildrenThreadsLock
java.lang.Throwable
java.lang.UnsatisfiedLinkError
java.lang.UnsupportedOperationException
java.lang.VMClassLoader
java.lang.VMThread
java.lang.VirtualMachineError
java.lang.Void
java.lang.annotation.Annotation
java.lang.ref.Reference
java.lang.ref.ReferenceQueue
java.lang.ref.SoftReference
java.lang.ref.WeakReference
java.lang.reflect.AccessibleObject
java.lang.reflect.AnnotatedElement
java.lang.reflect.Array
java.lang.reflect.Constructor
java.lang.reflect.Field
java.lang.reflect.GenericDeclaration
java.lang.reflect.InvocationHandler
java.lang.reflect.Member
java.lang.reflect.Method
java.lang.reflect.Modifier
java.lang.reflect.Proxy
java.lang.reflect.ReflectionAccessImpl
java.lang.reflect.Type
java.math.BigDecimal
java.math.BigInt
java.math.BigInteger
java.math.Multiplication
java.net.DatagramPacket
java.net.HttpURLConnection
java.net.Inet4Address
java.net.InetAddress
java.net.InetAddress$WaitReachable
java.net.InetSocketAddress
java.net.JarURLConnection
java.net.NetworkInterface
java.net.Proxy
java.net.ProxySelector
java.net.ProxySelectorImpl
java.net.ServerSocket
java.net.Socket
java.net.SocketImpl
java.net.SocketOptions
java.net.URI
java.net.URL
java.net.URLConnection
java.nio.BaseByteBuffer
java.nio.Buffer
java.nio.BufferFactory
java.nio.ByteBuffer
java.nio.ByteOrder
java.nio.CharArrayBuffer
java.nio.CharBuffer
java.nio.CharSequenceAdapter
java.nio.CharToByteBufferAdapter
java.nio.DirectByteBuffer
java.nio.FloatBuffer
java.nio.FloatToByteBufferAdapter
java.nio.HeapByteBuffer
java.nio.IntToByteBufferAdapter
java.nio.NIOAccess
java.nio.ReadWriteCharArrayBuffer
java.nio.ReadWriteDirectByteBuffer
java.nio.ReadWriteHeapByteBuffer
java.nio.ReadWriteIntArrayBuffer
java.nio.ShortToByteBufferAdapter
java.nio.channels.ByteChannel
java.nio.channels.Channel
java.nio.channels.FileChannel
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
java.nio.channels.ReadableByteChannel
java.nio.channels.ScatteringByteChannel
java.nio.channels.WritableByteChannel
java.nio.channels.spi.AbstractInterruptibleChannel
java.nio.channels.spi.AbstractInterruptibleChannel$1
java.nio.charset.Charset
java.nio.charset.Charset$1
java.nio.charset.CharsetDecoder
java.nio.charset.CharsetEncoder
java.nio.charset.CoderResult
java.nio.charset.CodingErrorAction
java.nio.charset.spi.CharsetProvider
java.security.AccessController
java.security.BasicPermission
java.security.Guard
java.security.KeyStore
java.security.MessageDigest
java.security.Permission
java.security.PrivilegedAction
java.security.PrivilegedExceptionAction
java.security.Provider
java.security.SecureRandom
java.security.Security
java.security.cert.CertificateParsingException
java.security.cert.PKIXParameters
java.security.cert.X509CertSelector
java.security.cert.X509Certificate
java.text.Collator
java.text.DateFormat
java.text.DateFormat$Field
java.text.DecimalFormat
java.text.DecimalFormatSymbols
java.text.Format
java.text.NumberFormat
java.text.SimpleDateFormat
java.util.AbstractCollection
java.util.AbstractList
java.util.AbstractMap
java.util.AbstractSet
java.util.ArrayList
java.util.Arrays
java.util.BitSet
java.util.Calendar
java.util.Collection
java.util.Collections
java.util.Collections$EmptyList
java.util.Collections$EmptyMap
java.util.Collections$EmptySet
java.util.Collections$SynchronizedList
java.util.Collections$SynchronizedRandomAccessList
java.util.Collections$UnmodifiableCollection
java.util.Collections$UnmodifiableCollection$1
java.util.Collections$UnmodifiableList
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
java.util.Comparator
java.util.Date
java.util.Dictionary
java.util.EnumMap
java.util.EnumSet
java.util.Enumeration
java.util.Formatter
java.util.GregorianCalendar
java.util.HashMap
java.util.HashMap$1
java.util.HashMap$1$1
java.util.HashMap$Entry
java.util.HashMap$HashMapIterator
java.util.HashSet
java.util.Hashtable
java.util.Hashtable$1
java.util.Hashtable$Entry
java.util.IdentityHashMap
java.util.Iterator
java.util.LinkedList
java.util.List
java.util.Locale
java.util.Map
java.util.Map$Entry
java.util.MapEntry
java.util.MapEntry$Type
java.util.PriorityQueue
java.util.Properties
java.util.PropertyPermission
java.util.RandomAccess
java.util.ResourceBundle
java.util.Scanner
java.util.Set
java.util.SimpleTimeZone
java.util.SortedMap
java.util.SortedSet
java.util.SpecialAccess
java.util.Stack
java.util.StringTokenizer
java.util.TimeZone
java.util.Timer
java.util.TreeMap
java.util.TreeSet
java.util.Vector
java.util.Vector$1
java.util.WeakHashMap
java.util.WeakHashMap$Entry
java.util.concurrent.AbstractExecutorService
java.util.concurrent.ArrayBlockingQueue
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.DelayQueue
java.util.concurrent.Executors$DelegatedExecutorService
java.util.concurrent.Executors$DelegatedScheduledExecutorService
java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.ScheduledThreadPoolExecutor
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
java.util.concurrent.Semaphore
java.util.concurrent.SynchronousQueue
java.util.concurrent.SynchronousQueue$Node
java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.TimeUnit
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicReference
java.util.concurrent.atomic.UnsafeAccess
java.util.concurrent.locks.AbstractQueuedSynchronizer
java.util.concurrent.locks.ReentrantLock
java.util.concurrent.locks.ReentrantLock$Sync
java.util.jar.Attributes$Name
java.util.jar.JarFile
java.util.jar.Manifest
java.util.logging.Level
java.util.logging.LogManager
java.util.logging.LogRecord
java.util.logging.Logger
java.util.regex.MatchResult
java.util.regex.Matcher
java.util.regex.Pattern
java.util.zip.Adler32
java.util.zip.CRC32
java.util.zip.Checksum
java.util.zip.Deflater
java.util.zip.DeflaterOutputStream
java.util.zip.Inflater
java.util.zip.ZipFile
javax.crypto.Cipher
javax.crypto.spec.SecretKeySpec
javax.microedition.khronos.egl.EGL
javax.microedition.khronos.egl.EGL10
javax.microedition.khronos.egl.EGLContext
javax.microedition.khronos.opengles.GL
javax.microedition.khronos.opengles.GL10
javax.microedition.khronos.opengles.GL10Ext
javax.microedition.khronos.opengles.GL11
javax.microedition.khronos.opengles.GL11Ext
javax.microedition.khronos.opengles.GL11ExtensionPack
javax.net.ssl.DefaultHostnameVerifier
javax.net.ssl.HttpsURLConnection
javax.net.ssl.SSLContext
javax.net.ssl.SSLHandshakeException
javax.net.ssl.SSLServerSocket
javax.net.ssl.SSLSession
javax.net.ssl.SSLSocket
javax.security.cert.X509Certificate
junit.framework.Assert
org.apache.commons.codec.binary.Base64
org.apache.commons.codec.binary.Hex
org.apache.commons.logging.LogFactory
org.apache.commons.logging.impl.Jdk14Logger
org.apache.harmony.dalvik.NativeTestTarget
org.apache.harmony.dalvik.ddmc.ChunkHandler
org.apache.harmony.dalvik.ddmc.DdmServer
org.apache.harmony.kernel.vm.LangAccess
org.apache.harmony.kernel.vm.ReflectionAccess
org.apache.harmony.lang.annotation.AnnotationFactory
org.apache.harmony.lang.annotation.AnnotationMember
org.apache.harmony.lang.annotation.AnnotationMember$DefaultValues
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection
org.apache.harmony.luni.internal.net.www.protocol.https.Handler
org.apache.harmony.luni.internal.net.www.protocol.jar.Handler
org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnection
org.apache.harmony.luni.internal.util.ZoneInfoDB
org.apache.harmony.luni.net.GenericIPMreq
org.apache.harmony.luni.net.PlainSocketImpl
org.apache.harmony.luni.platform.AdapterManager
org.apache.harmony.luni.platform.Endianness
org.apache.harmony.luni.platform.IAdaptable
org.apache.harmony.luni.platform.IAdapterManager
org.apache.harmony.luni.platform.ICommonDataTypes
org.apache.harmony.luni.platform.IFileSystem
org.apache.harmony.luni.platform.IMemorySystem
org.apache.harmony.luni.platform.INetworkSystem
org.apache.harmony.luni.platform.ISystemComponent
org.apache.harmony.luni.platform.OSComponent
org.apache.harmony.luni.platform.OSComponentFactory
org.apache.harmony.luni.platform.OSFileSystem
org.apache.harmony.luni.platform.OSMemory
org.apache.harmony.luni.platform.OSNetworkSystem
org.apache.harmony.luni.platform.Platform
org.apache.harmony.luni.platform.PlatformAddress
org.apache.harmony.luni.platform.PlatformAddressFactory
org.apache.harmony.luni.util.FloatingPointParser
org.apache.harmony.luni.util.NumberConverter
org.apache.harmony.luni.util.PriviAction
org.apache.harmony.luni.util.Util
org.apache.harmony.nio.AddressUtil
org.apache.harmony.nio.FileChannelFactory
org.apache.harmony.nio.internal.DirectBuffer
org.apache.harmony.nio.internal.FileChannelImpl
org.apache.harmony.nio.internal.FileChannelImpl$RepositioningLock
org.apache.harmony.nio.internal.LockManager
org.apache.harmony.nio.internal.LockManager$1
org.apache.harmony.nio.internal.WriteOnlyFileChannel
org.apache.harmony.security.asn1.ASN1GeneralizedTime
org.apache.harmony.security.asn1.ASN1Integer
org.apache.harmony.security.asn1.ASN1Oid
org.apache.harmony.security.asn1.ASN1Sequence
org.apache.harmony.security.asn1.ASN1StringType
org.apache.harmony.security.asn1.DerInputStream
org.apache.harmony.security.asn1.DerOutputStream
org.apache.harmony.security.fortress.Services
org.apache.harmony.security.pkcs7.ContentInfo
org.apache.harmony.security.provider.cert.DRLCertFactory
org.apache.harmony.security.provider.cert.X509CertFactoryImpl
org.apache.harmony.security.provider.cert.X509CertImpl
org.apache.harmony.security.provider.cert.X509CertPathImpl
org.apache.harmony.security.provider.crypto.RandomBitsSupplier
org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
org.apache.harmony.security.provider.crypto.SHA1_MessageDigestImpl
org.apache.harmony.security.utils.AlgNameMapper
org.apache.harmony.security.x501.AttributeTypeAndValue
org.apache.harmony.security.x501.DirectoryString
org.apache.harmony.security.x501.Name
org.apache.harmony.security.x509.AlgorithmIdentifier
org.apache.harmony.security.x509.BasicConstraints
org.apache.harmony.security.x509.Certificate
org.apache.harmony.security.x509.EDIPartyName
org.apache.harmony.security.x509.Extension
org.apache.harmony.security.x509.Extensions
org.apache.harmony.security.x509.GeneralName
org.apache.harmony.security.x509.GeneralNames
org.apache.harmony.security.x509.KeyUsage
org.apache.harmony.security.x509.ORAddress
org.apache.harmony.security.x509.OtherName
org.apache.harmony.security.x509.PolicyQualifierInfo
org.apache.harmony.security.x509.SubjectPublicKeyInfo
org.apache.harmony.security.x509.TBSCertificate
org.apache.harmony.security.x509.Time
org.apache.harmony.security.x509.Validity
org.apache.harmony.text.BidiWrapper
org.apache.harmony.xml.ExpatAttributes
org.apache.harmony.xml.ExpatParser
org.apache.harmony.xml.ExpatPullParser
org.apache.harmony.xml.ExpatPullParser$ByteDocument
org.apache.harmony.xml.ExpatReader
org.apache.harmony.xml.dom.AttrImpl
org.apache.harmony.xml.dom.CharacterDataImpl
org.apache.harmony.xml.dom.CommentImpl
org.apache.harmony.xml.dom.DocumentImpl
org.apache.harmony.xml.dom.ElementImpl
org.apache.harmony.xml.dom.InnerNodeImpl
org.apache.harmony.xml.dom.NodeImpl
org.apache.harmony.xml.dom.TextImpl
org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl
org.apache.harmony.xml.parsers.DocumentBuilderImpl
org.apache.harmony.xml.parsers.SAXParserFactoryImpl
org.apache.harmony.xnet.provider.jsse.AbstractSessionContext
org.apache.harmony.xnet.provider.jsse.FileClientSessionCache
org.apache.harmony.xnet.provider.jsse.NativeCrypto
org.apache.harmony.xnet.provider.jsse.OpenSSLServerSocketImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$Finalizer
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$LoggerHolder
org.apache.harmony.xnet.provider.jsse.ProtocolVersion
org.apache.harmony.xnet.provider.jsse.SSLContextImpl
org.apache.harmony.xnet.provider.jsse.SSLParameters
org.apache.harmony.xnet.provider.jsse.ServerSessionContext
org.apache.http.HttpVersion
org.apache.http.NoHttpResponseException
org.apache.http.ProtocolException
org.apache.http.client.HttpClient
org.apache.http.client.methods.HttpEntityEnclosingRequestBase
org.apache.http.client.methods.HttpGet
org.apache.http.client.methods.HttpPost
org.apache.http.client.methods.HttpRequestBase
org.apache.http.conn.BasicManagedEntity
org.apache.http.conn.params.ConnManagerParams
org.apache.http.conn.params.ConnRouteParams
org.apache.http.conn.routing.HttpRoute
org.apache.http.conn.scheme.PlainSocketFactory
org.apache.http.conn.ssl.AbstractVerifier
org.apache.http.conn.ssl.SSLSocketFactory
org.apache.http.conn.util.InetAddressUtils
org.apache.http.entity.BasicHttpEntity
org.apache.http.entity.InputStreamEntity
org.apache.http.entity.StringEntity
org.apache.http.impl.AbstractHttpClientConnection
org.apache.http.impl.EnglishReasonPhraseCatalog
org.apache.http.impl.HttpConnectionMetricsImpl
org.apache.http.impl.SocketHttpClientConnection
org.apache.http.impl.client.AbstractAuthenticationHandler
org.apache.http.impl.client.AbstractHttpClient
org.apache.http.impl.client.DefaultHttpClient
org.apache.http.impl.client.EntityEnclosingRequestWrapper
org.apache.http.impl.conn.AbstractClientConnAdapter
org.apache.http.impl.conn.AbstractPooledConnAdapter
org.apache.http.impl.conn.DefaultClientConnection
org.apache.http.impl.conn.SingleClientConnManager
org.apache.http.impl.conn.tsccm.ConnPoolByRoute
org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
org.apache.http.impl.cookie.BasicClientCookie
org.apache.http.impl.cookie.BrowserCompatSpec
org.apache.http.impl.cookie.DateUtils
org.apache.http.impl.cookie.RFC2109Spec
org.apache.http.impl.cookie.RFC2965Spec
org.apache.http.impl.io.AbstractSessionInputBuffer
org.apache.http.impl.io.SocketInputBuffer
org.apache.http.message.AbstractHttpMessage
org.apache.http.message.BasicHeaderElement
org.apache.http.message.BasicHttpEntityEnclosingRequest
org.apache.http.message.BasicHttpRequest
org.apache.http.message.BasicHttpResponse
org.apache.http.message.BasicLineFormatter
org.apache.http.message.BasicLineParser
org.apache.http.message.BasicTokenIterator
org.apache.http.params.AbstractHttpParams
org.apache.http.params.BasicHttpParams
org.apache.http.protocol.BasicHttpProcessor
org.apache.http.protocol.HTTP
org.bouncycastle.asn1.DERNull
org.bouncycastle.asn1.DERObject
org.bouncycastle.asn1.DERObjectIdentifier
org.bouncycastle.asn1.iana.IANAObjectIdentifiers
org.bouncycastle.asn1.nist.NISTObjectIdentifiers
org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
org.bouncycastle.asn1.x509.X509Extensions
org.bouncycastle.asn1.x509.X509Name
org.bouncycastle.crypto.digests.SHA1Digest
org.bouncycastle.crypto.engines.AESFastEngine
org.bouncycastle.crypto.generators.PKCS12ParametersGenerator
org.bouncycastle.crypto.macs.HMac
org.bouncycastle.jce.provider.BouncyCastleProvider
org.bouncycastle.jce.provider.CertPathValidatorUtilities
org.bouncycastle.jce.provider.JCEBlockCipher
org.bouncycastle.jce.provider.JCEBlockCipher$AES
org.bouncycastle.jce.provider.JCEMac
org.bouncycastle.jce.provider.JDKKeyFactory
org.bouncycastle.jce.provider.JDKKeyFactory$RSA
org.bouncycastle.jce.provider.JDKKeyStore
org.bouncycastle.jce.provider.JDKX509CertificateFactory
org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
org.bouncycastle.jce.provider.WrapCipherSpi
org.bouncycastle.jce.provider.X509CertificateObject
org.ccil.cowan.tagsoup.AttributesImpl
org.ccil.cowan.tagsoup.HTMLScanner
org.ccil.cowan.tagsoup.HTMLSchema
org.ccil.cowan.tagsoup.Parser
org.json.JSONObject
org.kxml2.io.KXmlParser
org.kxml2.io.KXmlSerializer
org.openssl.NativeBN
org.xml.sax.Attributes
org.xml.sax.helpers.DefaultHandler
org.xmlpull.v1.XmlPullParser
org.xmlpull.v1.XmlPullParserException
org.xmlpull.v1.sax2.Driver
sun.misc.Unsafe

preloadClass函数的执行时间比较长,这是导致Android系统启动慢的原因之一

启动system_server

startSystemServer 这个函数会创建Java世界中系统Service所驻留的进程system_server,该进程是framework的核心

 /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer() 
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
          //设置参数
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",//进程名,叫system_server
            "com.android.server.SystemServer", //启动的类名
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
        //把上面字符串数组参数转换成Arguments对象
            parsedArgs = new ZygoteConnection.Arguments(args);

            /*
             * Enable debugging of the system process if *either* the command line flags
             * indicate it should be debuggable or the ro.debuggable system property
             * is set to "1"
             */
            int debugFlags = parsedArgs.debugFlags;
            if ("1".equals(SystemProperties.get("ro.debuggable")))
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            /* Request to fork the system server process */
             //fork一个子进程,看来,这个子进程就是system_server进程。
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        } 
 
        /* For child process */
        if (pid == 0) {
         //① system_server进程的工作
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

Zygote进行了一次无性繁殖,分裂出了一个system_server进程

有求必应之等待请求——runSelectLoopMode

前面,在第一个关键点registerZygoteSocket中注册了一个用于IPC的Socket,不过那时还没有地方用到它。它的用途将在这个runSelectLoopMode中体现出来

 /**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     *
     * @throws MethodAndArgsCaller in a child process when a main() should
     * be executed.
     */
    private static void runSelectLoopMode() throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList();
        ArrayList<ZygoteConnection> peers = new ArrayList();
        FileDescriptor[] fdArray = new FileDescriptor[4];
 //sServerSocket是我们先前在registerZygoteSocket建立的Socket
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        while (true) {
            int index;

            /*
             * Call gc() before we block in select().
             * It's work that has to be done anyway, and it's better
             * to avoid making every child do it.  It will also
             * madvise() any free memory as a side-effect.
             *
             * Don't call it every time, because walking the entire
             * heap is a lot of overhead to free a few hundred bytes.
             */
            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }


            try {
                fdArray = fds.toArray(fdArray);
                 /*
          selectReadable内部调用select,使用多路复用I/O模型。
          当有客户端连接或有数据时,则selectReadable就会返回。
        */
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
              //如有一个客户端连接上,请注意客户端在Zygote的代表是ZygoteConnection
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done;
                 //客户端发送了请求,peers.get返回的是ZygoteConnection
                 //后续处理将交给ZygoteConnection的runOnce函数完成。
                done = peers.get(index).runOnce();

                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }

处理客户连接和客户请求。其中客户在Zygote中用ZygoteConnection对象来表示。
客户的请求由ZygoteConnection的runOnce来处理。

SystemServer的诞生

通过Zygote.forkSystemServer函数fork诞生出来的
dalvik\vm\native\dalvik_system_Zygote.c 实现在这个类中

/* native public static int fork(); */
static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult)
{
    pid_t pid;
    int err;

    if (!gDvm.zygote) {
        dvmThrowException("Ljava/lang/IllegalStateException;",
            "VM instance not started with -Xzygote");

        RETURN_VOID();
    }

    if (!dvmGcPreZygoteFork()) {
        LOGE("pre-fork heap failed\n");
        dvmAbort();
    }
  //设置信号处理
    setSignalHandler();      

    dvmDumpLoaderStats("zygote");
    pid = fork();  //设置信号处理

#ifdef HAVE_ANDROID_OS
    if (pid == 0) {
        /* child process */
        extern int gMallocLeakZygoteChild;
        gMallocLeakZygoteChild = 1;
    }
#endif

    RETURN_INT(pid);
}

setSignalHandler函数,它由Zygote在fork子进程前调用

/*
 * configure sigchld handler for the zygote process
 * This is configured very late, because earlier in the dalvik lifecycle
 * we can fork() and exec() for the verifier/optimizer, and we
 * want to waitpid() for those rather than have them be harvested immediately.
 *
 * This ends up being called repeatedly before each fork(), but there's
 * no real harm in that.
 */
static void setSignalHandler() 
{
    int err;
    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));

    sa.sa_handler = sigchldHandler;
//设置信号处理函数,该信号是子进程死亡的信号
    err = sigaction (SIGCHLD, &sa, NULL);
    
    if (err < 0) {
        LOGW("Error setting SIGCHLD handler errno: %d", errno);
    }
}

//我们直接看这个信号处理函数sigchldHandler
/*
 * This signal handler is for zygote mode, since the zygote
 * must reap its children
 */
static void sigchldHandler(int s)
{
    pid_t pid;
    int status;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        /* Log process-death status that we care about.  In general it is not
           safe to call LOG(...) from a signal handler because of possible
           reentrancy.  However, we know a priori that the current implementation
           of LOG() is safe to call from a SIGCHLD handler in the zygote process.
           If the LOG() implementation changes its locking strategy or its use
           of syscalls within the lazy-init critical section, its use here may
           become unsafe. */
        if (WIFEXITED(status)) {
            if (WEXITSTATUS(status)) {
                LOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)\n",
                    (int) pid, WEXITSTATUS(status));
            } else {
                IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
                    LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
                        "Process %d exited cleanly (%d)\n",
                        (int) pid, WEXITSTATUS(status));
                }
            }
        } else if (WIFSIGNALED(status)) {
            if (WTERMSIG(status) != SIGKILL) {
                LOG(LOG_DEBUG, ZYGOTE_LOG_TAG,
                    "Process %d terminated by signal (%d)\n",
                    (int) pid, WTERMSIG(status));
            } else {
                IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
                    LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
                        "Process %d terminated by signal (%d)\n",
                        (int) pid, WTERMSIG(status));
                }
            }
#ifdef WCOREDUMP
            if (WCOREDUMP(status)) {
                LOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core\n",
                    (int) pid);
            }
#endif /* ifdef WCOREDUMP */
        }

        /* 
         * If the just-crashed process is the system_server, bring down zygote
         * so that it is restarted by init and system server will be restarted
         * from there.
         */
         //如果死去的子进程是SystemServer,则Zygote把自己也干掉了,这样就做到了生死与共!
        if (pid == gDvm.systemServerPid) {
            LOG(LOG_INFO, ZYGOTE_LOG_TAG,
                "Exit zygote because system server (%d) has terminated\n", 
                (int) pid);
            kill(getpid(), SIGKILL);
        }
    }

    if (pid < 0) {
        LOG(LOG_WARN, ZYGOTE_LOG_TAG,
            "Zygote SIGCHLD error (%d) in waitpid\n",errno);
    }
}

SystemServer的重要使命

SystemServer调用handleSystemServerProcess来承担自己的职责。

 /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
        /*
         * First, set the capabilities if necessary
         */

        if (parsedArgs.uid != 0) {
            try {
                setCapabilities(parsedArgs.permittedCapabilities,
                                parsedArgs.effectiveCapabilities);
            } catch (IOException ex) {
                Log.e(TAG, "Error setting capabilities", ex);
            }
        }
 //关闭从Zygote那里继承下来的Socket。
        closeServerSocket();

        /*
         * Pass the remaining arguments to SystemServer.
         * "--nice-name=system_server com.android.server.SystemServer"
         */
         //调用ZygoteInit函数。
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        /* should never reach here */
    }

RuntimeInit.zygoteInit
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

/**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in finishInit()
     * were rationalized with Zygote startup.<p>
     *
     * Current recognized args:
     * <ul>
     *   <li> --nice-name=<i>nice name to appear in ps</i>
     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
     * </ul>
     *
     * @param argv arg strings
     */
    public static final void zygoteInit(String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        // TODO: Doing this here works, but it seems kind of arbitrary. Find
        // a better place. The goal is to set it up for applications, but not
        // tools like am.
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
//做一些常规初始化
        commonInit();
         //①native层的初始化。
        zygoteInitNative();

        int curArg = 0;
        for ( /* curArg */ ; curArg < argv.length; curArg++) {
            String arg = argv[curArg];

            if (arg.equals("--")) {
                curArg++;
                break;
            } else if (!arg.startsWith("--")) {
                break;
            } else if (arg.startsWith("--nice-name=")) {
                String niceName = arg.substring(arg.indexOf('=') + 1);
                //设置进程名为niceName,也就是"system_server"
                Process.setArgV0(niceName);
            }
        }

        if (curArg == argv.length) {
            Log.e(TAG, "Missing classname argument to RuntimeInit!");
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main
        //startClass名为"com.android.server.SystemServer"
        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];

        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
        //②调用startClass,也就是com.android.server.SystemServer类的main函数。
        invokeStaticMain(startClass, startArgs);
    }

zygoteInitNative分析

frameworks\base\core\jni\AndroidRuntime.cpp

static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
//gCurRuntime是什么 就是  AppRuntime runtime;
/*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;


AndroidRuntime::AndroidRuntime()
{
//Skia库初始化
    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被设置为AndroidRuntime对象自己
    gCurRuntime = this;
}
frameworks\base\cmds\app_process\app_main.cpp
virtual void onZygoteInit()
    {
    //下面这些东西和Binder有关系
        sp<ProcessState> proc = ProcessState::self();
        if (proc->supportsProcesses()) {
            LOGV("App process: starting thread pool.\n");
            //启动一个线程,用于Binder通信。
            proc->startThreadPool();
        }       
    }

invokeStaticMain分析

zygoteInit 函数中的 invokeStaticMain

/**
     * Invokes a static "main(argv[]) method on class "className".
     * Converts various failing exceptions into RuntimeExceptions, with
     * the assumption that they will then cause the VM instance to exit.
     *
     * @param className Fully-qualified class name
     * @param argv Argument vector for main()
     */
    private static void invokeStaticMain(String className, String[] argv) 
            throws ZygoteInit.MethodAndArgsCaller {
        
        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        //注意我们的参数,className为"com.android.server.SystemServer"
        Class<?> cl;

        try {
            cl = Class.forName(className);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
        //找到com.android.server.SystemServer类的main函数,肯定有地方要调用它
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
         //抛出一个异常 在ZygoteInit的main函数中被截获
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

ZygoteInit分裂产生的SystemServer,其实就是为了调用com.android.server.SystemServer的main函数
frameworks\base\services\java\com\android\server\SystemServer.java

public static void main(String[] args) {
        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
         //加载libandroid_servers.so
        System.loadLibrary("android_servers");
         //调用native的init1函数。
        init1(args);
    }

其中main函数将加载libandroid_server.so库,这个库所包含的源码文件在文件夹framework/base/services/jni下

init1分析

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
//调用另外一个函数。
    system_init();
}
frameworks\base\cmds\system_server\library\system_init.cpp

extern "C" status_t system_init()
{
    LOGI("Entered system_init()");
     //下面这些调用和Binder有关
    sp<ProcessState> proc(ProcessState::self());
    
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p\n", sm.get());
    
    sp<GrimReaper> grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
    
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        //SurfaceFlinger服务在system_server进程创建
        SurfaceFlinger::instantiate();
    }

    // On the simulator, audioflinger et al don't get started the
    // same way as on the device, and we need to start them here
    if (!proc->supportsProcesses()) {

        // Start the AudioFlinger
        AudioFlinger::instantiate();

        // Start the media playback service
        MediaPlayerService::instantiate();

        // Start the camera service
        CameraService::instantiate();
    }

    // And now start the Android runtime.  We have to do this bit
    // of nastiness because the Android runtime initialization requires
    // some of the core system services to already be started.
    // All other servers should just start the Android runtime at
    // the beginning of their processes's main(), before calling
    // the init function.
    LOGI("System server: starting Android runtime.\n");
    
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

    LOGI("System server: starting Android services.\n");
    //调用com.android.server.SystemServer类的init2函数
    runtime->callStatic("com/android/server/SystemServer", "init2");
        
    // If running in our own process, just go into the thread
    // pool.  Otherwise, call the initialization finished
    // func to let this process continue its initilization.
    if (proc->supportsProcesses()) {
        LOGI("System server: entering thread pool.\n");
        ProcessState::self()->startThreadPool();
        //调用joinThreadPool后,当前线程也加入到Binder通信的大潮中
        IPCThreadState::self()->joinThreadPool();
        LOGI("System server: exiting thread pool.\n");
    }
    return NO_ERROR;
}

init2 分析

public static final void init2() {
        Log.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        //启动一个ServerThread
        //启动了一个ServerThread线程。请直接看它的run函数
        thr.start();
    }

SystemServer.java::ServerThread的run函数

@Override
    public void run() {
        EventLog.writeEvent(LOG_BOOT_PROGRESS_SYSTEM_RUN,
            SystemClock.uptimeMillis());

        ActivityManagerService.prepareTraceFile(false);     // create dir

        Looper.prepare();

        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);

        String factoryTestStr = SystemProperties.get("ro.factorytest");
        int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                : Integer.parseInt(factoryTestStr);

        HardwareService hardware = null;
        PowerManagerService power = null;
        IPackageManager pm = null;
        Context context = null;
        WindowManagerService wm = null;
        BluetoothDeviceService bluetooth = null;
        BluetoothA2dpService bluetoothA2dp = null;
        HeadsetObserver headset = null;

        // Critical services...
        try {
            Log.i(TAG, "Starting Entropy Service.");
            //启动Entropy Service
            ServiceManager.addService("entropy", new EntropyService());

            Log.i(TAG, "Starting Power Manager.");
            //启动电源管理服务
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);

            Log.i(TAG, "Starting Activity Manager.");
            context = ActivityManagerService.main(factoryTest);

            Log.i(TAG, "Starting telephony registry");
            ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));

            AttributeCache.init(context);

            Log.i(TAG, "Starting Package Manager.");
            pm = PackageManagerService.main(context,
                    factoryTest != SystemServer.FACTORY_TEST_OFF);

            ActivityManagerService.setSystemProcess();

            mContentResolver = context.getContentResolver();

            Log.i(TAG, "Starting Content Manager.");
            ContentService.main(context,
                    factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

            Log.i(TAG, "Starting System Content Providers.");
            ActivityManagerService.installSystemProviders();

            Log.i(TAG, "Starting Battery Service.");
            BatteryService battery = new BatteryService(context);
            ServiceManager.addService("battery", battery);

            Log.i(TAG, "Starting Hardware Service.");
            hardware = new HardwareService(context);
            ServiceManager.addService("hardware", hardware);

            // only initialize the power service after we have started the
            // hardware service, content providers and the battery service.
            power.init(context, hardware, ActivityManagerService.getDefault(), battery);

            Log.i(TAG, "Starting Alarm Manager.");
            AlarmManagerService alarm = new AlarmManagerService(context);
            ServiceManager.addService(Context.ALARM_SERVICE, alarm);
 			//初始化看门狗
            Watchdog.getInstance().init(context, battery, power, alarm,
                    ActivityManagerService.self());

            // Sensor Service is needed by Window Manager, so this goes first
            Log.i(TAG, "Starting Sensor Service.");
            ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context));

            Log.i(TAG, "Starting Window Manager.");
              //启动WindowManager服务
            wm = WindowManagerService.main(context, power,
                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
             //启动ActivityManager服务
 				((ActivityManagerService)ServiceManager.getService("activity"))
                    .setWindowManager(wm);

            // Skip Bluetooth if we have an emulator kernel
            // TODO: Use a more reliable check to see if this product should
            // support Bluetooth - see bug 988521
            if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
                Log.i(TAG, "Registering null Bluetooth Service (emulator)");
                ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
            } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                Log.i(TAG, "Registering null Bluetooth Service (factory test)");
                ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
            } else {
                Log.i(TAG, "Starting Bluetooth Service.");
                bluetooth = new BluetoothDeviceService(context);
                bluetooth.init();
                ServiceManager.addService(Context.BLUETOOTH_SERVICE, bluetooth);
                bluetoothA2dp = new BluetoothA2dpService(context);
                ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
                                          bluetoothA2dp);

                int bluetoothOn = Settings.Secure.getInt(mContentResolver,
                    Settings.Secure.BLUETOOTH_ON, 0);
                if (bluetoothOn > 0) {
                    bluetooth.enable();
                }
            }

        } catch (RuntimeException e) {
            Log.e("System", "Failure starting core service", e);
        }

        StatusBarService statusBar = null;
        InputMethodManagerService imm = null;
        AppWidgetService appWidget = null;
        NotificationManagerService notification = null;

        if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
            try {
                Log.i(TAG, "Starting Status Bar Service.");
                statusBar = new StatusBarService(context);
                ServiceManager.addService("statusbar", statusBar);
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting StatusBarService", e);
            }

            try {
                Log.i(TAG, "Starting Clipboard Service.");
                ServiceManager.addService("clipboard", new ClipboardService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Clipboard Service", e);
            }

            try {
                Log.i(TAG, "Starting Input Method Service.");
                imm = new InputMethodManagerService(context, statusBar);
                ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Input Manager Service", e);
            }

            try {
                Log.i(TAG, "Starting NetStat Service.");
                ServiceManager.addService("netstat", new NetStatService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting NetStat Service", e);
            }

            try {
                Log.i(TAG, "Starting Connectivity Service.");
                ServiceManager.addService(Context.CONNECTIVITY_SERVICE,
                        ConnectivityService.getInstance(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Connectivity Service", e);
            }

            try {
              Log.i(TAG, "Starting Accessibility Manager.");
              ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
                      new AccessibilityManagerService(context));
            } catch (Throwable e) {
              Log.e(TAG, "Failure starting Accessibility Manager", e);
            }

            try {
                Log.i(TAG, "Starting Notification Manager.");
                notification = new NotificationManagerService(context, statusBar, hardware);
                ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Notification Manager", e);
            }

            try {
                // MountService must start after NotificationManagerService
                Log.i(TAG, "Starting Mount Service.");
                ServiceManager.addService("mount", new MountService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Mount Service", e);
            }

            try {
                Log.i(TAG, "Starting DeviceStorageMonitor service");
                ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
                        new DeviceStorageMonitorService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting DeviceStorageMonitor service", e);
            }

            try {
                Log.i(TAG, "Starting Location Manager.");
                ServiceManager.addService(Context.LOCATION_SERVICE, new LocationManagerService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Location Manager", e);
            }

            try {
                Log.i(TAG, "Starting Search Service.");
                ServiceManager.addService( Context.SEARCH_SERVICE, new SearchManagerService(context) );
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Search Service", e);
            }

            if (INCLUDE_DEMO) {
                Log.i(TAG, "Installing demo data...");
                (new DemoThread(context)).start();
            }

            try {
                Log.i(TAG, "Starting Checkin Service.");
                Intent intent = new Intent().setComponent(new ComponentName(
                        "com.google.android.server.checkin",
                        "com.google.android.server.checkin.CheckinService"));
                if (context.startService(intent) == null) {
                    Log.w(TAG, "Using fallback Checkin Service.");
                    ServiceManager.addService("checkin", new FallbackCheckinService(context));
                }
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Checkin Service", e);
            }

            try {
                Log.i(TAG, "Starting Wallpaper Service");
                ServiceManager.addService(Context.WALLPAPER_SERVICE, new WallpaperService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Wallpaper Service", e);
            }

            try {
                Log.i(TAG, "Starting Audio Service");
                ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Audio Service", e);
            }

            try {
                Log.i(TAG, "Starting HeadsetObserver");
                // Listen for wired headset changes
                headset = new HeadsetObserver(context);
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting HeadsetObserver", e);
            }

            try {
                if (INCLUDE_BACKUP) {
                    Log.i(TAG, "Starting Backup Service");
                    ServiceManager.addService(Context.BACKUP_SERVICE, new BackupManagerService(context));
                }
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting Backup Service", e);
            }

            try {
                Log.i(TAG, "Starting AppWidget Service");
                appWidget = new AppWidgetService(context);
                ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
            } catch (Throwable e) {
                Log.e(TAG, "Failure starting AppWidget Service", e);
            }

            try {
                com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
            } catch (Throwable e) {
                Log.e(TAG, "Failure installing status bar icons", e);
            }
        }

        // make sure the ADB_ENABLED setting value matches the secure property value
        Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_ENABLED,
                "1".equals(SystemProperties.get("persist.service.adb.enable")) ? 1 : 0);

        // register observer to listen for settings changes
        mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
                false, new AdbSettingsObserver());

        // It is now time to start up the app processes...
        boolean safeMode = wm.detectSafeMode();

        if (notification != null) {
            notification.systemReady();
        }

        if (statusBar != null) {
            statusBar.systemReady();
        }
        if (imm != null) {
            imm.systemReady();
        }
        wm.systemReady();
        power.systemReady();
        try {
            pm.systemReady();
        } catch (RemoteException e) {
        }
        if (appWidget != null) {
            appWidget.systemReady(safeMode);
        }

        // After making the following code, third party code may be running...
        try {
            ActivityManagerNative.getDefault().systemReady();
        } catch (RemoteException e) {
        }

        Watchdog.getInstance().start();
		//系统各种重要服务都在这里启动
        Looper.loop();
        Log.d(TAG, "System ServerThread is exiting!");
    }

init2函数比较简单,就是单独创建一个线程,用以启动系统各项服务

Zygote的分裂

Zygote分裂出嫡长子system_server后就通过runSelectLoopMode等待并处理来自客户的消息
谁会向Zygote发送消息呢

ActivityManagerService发送请求

ActivityManagerService也是由SystemServer创建的。假设通过startActivit来启动一个新的Activity,而这个Activity附属于一个还未启动的进程,那么这个进程该如何启动呢

先来看看ActivityManagerService中的startProcessLocked函数
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java

private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        if (app.pid > 0 && app.pid != MY_PID) {
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.remove(app.pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            app.pid = 0;
        }

        mProcessesOnHold.remove(app);

        updateCpuStats();
        
        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
        mProcDeaths[0] = 0;
        
        try {
            int uid = app.info.uid;
            int[] gids = null;
            try {
                gids = mContext.getPackageManager().getPackageGids(
                        app.info.packageName);
            } catch (PackageManager.NameNotFoundException e) {
                Log.w(TAG, "Unable to retrieve gids", e);
            }
            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                        && mTopComponent != null
                        && app.processName.equals(mTopComponent.getPackageName())) {
                    uid = 0;
                }
                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
                    uid = 0;
                }
            }
            int debugFlags = 0;
            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
            }
            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
            }
            if ("1".equals(SystemProperties.get("debug.assert"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
            }
              //这个Process类是Android提供的,并非JDK中的Process类
            int pid = Process.start("android.app.ActivityThread",
                    mSimpleProcessManagement ? app.processName : null, uid, uid,
                    gids, debugFlags, null);
            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
            synchronized (bs) {
                if (bs.isOnBattery()) {
                    app.batteryStats.incStartsLocked();
                }
            }
            
            EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
                    app.processName, hostingType,
                    hostingNameStr != null ? hostingNameStr : "");
            
            if (app.persistent) {
                Watchdog.getInstance().processStarted(app, app.processName, pid);
            }
            
            StringBuilder buf = mStringBuilder;
            buf.setLength(0);
            buf.append("Start proc ");
            buf.append(app.processName);
            buf.append(" for ");
            buf.append(hostingType);
            if (hostingNameStr != null) {
                buf.append(" ");
                buf.append(hostingNameStr);
            }
            buf.append(": pid=");
            buf.append(pid);
            buf.append(" uid=");
            buf.append(uid);
            buf.append(" gids={");
            if (gids != null) {
                for (int gi=0; gi<gids.length; gi++) {
                    if (gi != 0) buf.append(", ");
                    buf.append(gids[gi]);

                }
            }
            buf.append("}");
            Log.i(TAG, buf.toString());
            if (pid == 0 || pid == MY_PID) {
                // Processes are being emulated with threads.
                app.pid = MY_PID;
                app.removed = false;
                mStartingProcesses.add(app);
            } else if (pid > 0) {
                app.pid = pid;
                app.removed = false;
                synchronized (mPidsSelfLocked) {
                    this.mPidsSelfLocked.put(pid, app);
                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                    msg.obj = app;
                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
                }
            } else {
                app.pid = 0;
                RuntimeException e = new RuntimeException(
                        "Failure starting process " + app.processName
                        + ": returned pid=" + pid);
                Log.e(TAG, e.getMessage(), e);
            }
        } catch (RuntimeException e) {
            // XXX do better error recovery.
            app.pid = 0;
            Log.e(TAG, "Failure starting process " + app.processName, e);
        }
    }

Process的start函数,这个Process类是android.os.Process
frameworks\base\core\java\android\os\Process.java

/**
     * Start a new process.
     * 
     * <p>If processes are enabled, a new process is created and the
     * static main() function of a <var>processClass</var> is executed there.
     * The process will continue running after this function returns.
     * 
     * <p>If processes are not enabled, a new thread in the caller's
     * process is created and main() of <var>processClass</var> called there.
     * 
     * <p>The niceName parameter, if not an empty string, is a custom name to
     * give to the process instead of using processClass.  This allows you to
     * make easily identifyable processes even if you are using the same base
     * <var>processClass</var> to start them.
     * 
     * @param processClass The class to use as the process's main entry
     *                     point.
     * @param niceName A more readable name to use for the process.
     * @param uid The user-id under which the process will run.
     * @param gid The group-id under which the process will run.
     * @param gids Additional group-ids associated with the process.
     * @param enableDebugger True if debugging should be enabled for this process.
     * @param zygoteArgs Additional arguments to supply to the zygote process.
     * 
     * @return int If > 0 the pid of the new process; if 0 the process is
     *         being emulated by a thread
     * @throws RuntimeException on fatal start failure
     * 
     * {@hide}
     */
    public static final int start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags,
                                  String[] zygoteArgs)
    {
    //processClass的值是"android.app.ActivityThread"
        if (supportsProcesses()) {
            try {
                return startViaZygote(processClass, niceName, uid, gid, gids,
                        debugFlags, zygoteArgs);
            } catch (ZygoteStartFailedEx ex) {
                Log.e(LOG_TAG,
                        "Starting VM process through Zygote failed");
                throw new RuntimeException(
                        "Starting VM process through Zygote failed", ex);
            }
        } else {
            // Running in single-process mode
            
            Runnable runnable = new Runnable() {
                        public void run() {
                            Process.invokeStaticMain(processClass);
                        }
            };
            
            // Thread constructors must not be called with null names (see spec). 
            if (niceName != null) {
                new Thread(runnable, niceName).start();
            } else {
                new Thread(runnable).start();
            }
            
            return 0;
        }
    }

Process.java::startViaZygote()

 /**
     * Starts a new process via the zygote mechanism.
     *
     * @param processClass Class name whose static main() to run
     * @param niceName 'nice' process name to appear in ps
     * @param uid a POSIX uid that the new process should setuid() to
     * @param gid a POSIX gid that the new process shuold setgid() to
     * @param gids null-ok; a list of supplementary group IDs that the
     * new process should setgroup() to.
     * @param enableDebugger True if debugging should be enabled for this process.
     * @param extraArgs Additional arguments to supply to the zygote process.
     * @return PID
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private static int startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
        int pid;

        synchronized(Process.class) {
            ArrayList<String> argsForZygote = new ArrayList<String>();
.//一些参数处理,最后调用zygoteSendArgsAndGetPid函数。
            // --runtime-init, --setuid=, --setgid=,
            // and --setgroups= must go first
            argsForZygote.add("--runtime-init");//这个参数很重要
            argsForZygote.add("--setuid=" + uid);
            argsForZygote.add("--setgid=" + gid);
            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
                argsForZygote.add("--enable-debugger");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
                argsForZygote.add("--enable-checkjni");
            }
            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                argsForZygote.add("--enable-assert");
            }

            //TODO optionally enable debuger
            //argsForZygote.add("--enable-debugger");

            // --setgroups is a comma-separated list
            if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");

                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }

                argsForZygote.add(sb.toString());
            }

            if (niceName != null) {
                argsForZygote.add("--nice-name=" + niceName);
            }

            argsForZygote.add(processClass);

            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
            
            pid = zygoteSendArgsAndGetPid(argsForZygote);
        }

        if (pid <= 0) {
            throw new ZygoteStartFailedEx("zygote start failed:" + pid);
        }

        return pid;
    }

Process.java::zygoteSendArgsAndGetPid()

/**
     * Sends an argument list to the zygote process, which starts a new child
     * and returns the child's pid. Please note: the present implementation
     * replaces newlines in the argument list with spaces.
     * @param args argument list
     * @return PID of new child process
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
            throws ZygoteStartFailedEx {

        int pid;
// openZygoteSocketIfNeeded?是不是打开了和Zygote通信的Socket?
        openZygoteSocketIfNeeded();

        try {
            /**
             * See com.android.internal.os.ZygoteInit.readArgumentList()
             * Presently the wire format to the zygote process is:
             * a) a count of arguments (argc, in essence)
             * b) a number of newline-separated argument strings equal to count
             *
             * After the zygote process reads these it will write the pid of
             * the child or -1 on failure.
             */

             //把请求的参数发到Zygote。sZygoteWriter.write(Integer.toString(args.size()));
            sZygoteWriter.newLine();

            int sz = args.size();
            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                if (arg.indexOf('\n') >= 0) {
                    throw new ZygoteStartFailedEx(
                            "embedded newlines not allowed");
                }
                sZygoteWriter.write(arg);
                sZygoteWriter.newLine();
            }
//读取Zygote处理完的结果,便得知是某个进程的pid!
            sZygoteWriter.flush();

            // Should there be a timeout on this?
            pid = sZygoteInputStream.readInt();

            if (pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
        } catch (IOException ex) {
            try {
                if (sZygoteSocket != null) {
                    sZygoteSocket.close();
                }
            } catch (IOException ex2) {
                // we're going to fail anyway
                Log.e(LOG_TAG,"I/O exception on routine close", ex2);
            }

            sZygoteSocket = null;

            throw new ZygoteStartFailedEx(ex);
        }

        return pid;
    }

openZygoteSocketIfNeeded

/**
     * Tries to open socket to Zygote process if not already open. If
     * already open, does nothing.  May block and retry.
     */
    private static void openZygoteSocketIfNeeded() 
            throws ZygoteStartFailedEx {

        int retryCount;

        if (sPreviousZygoteOpenFailed) {
            /*
             * If we've failed before, expect that we'll fail again and
             * don't pause for retries.
             */
            retryCount = 0;
        } else {
            retryCount = 10;            
        }

        /*
         * See bug #811181: Sometimes runtime can make it up before zygote.
         * Really, we'd like to do something better to avoid this condition,
         * but for now just wait a bit...
         */
        for (int retry = 0
                ; (sZygoteSocket == null) && (retry < (retryCount + 1))
                ; retry++ ) {

            if (retry > 0) {
                try {
                    Log.i("Zygote", "Zygote not up yet, sleeping...");
                    Thread.sleep(ZYGOTE_RETRY_MILLIS);
                } catch (InterruptedException ex) {
                    // should never happen
                }
            }

            try {
                sZygoteSocket = new LocalSocket();
				 //连接Zygote
                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, 
                        LocalSocketAddress.Namespace.RESERVED));

                sZygoteInputStream
                        = new DataInputStream(sZygoteSocket.getInputStream());

                sZygoteWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    sZygoteSocket.getOutputStream()),
                            256);

                Log.i("Zygote", "Process: zygote socket opened");

                sPreviousZygoteOpenFailed = false;
                break;
            } catch (IOException ex) {
                if (sZygoteSocket != null) {
                    try {
                        sZygoteSocket.close();
                    } catch (IOException ex2) {
                        Log.e(LOG_TAG,"I/O exception on close after exception",
                                ex2);
                    }
                }

                sZygoteSocket = null;
            }
        }

        if (sZygoteSocket == null) {
            sPreviousZygoteOpenFailed = true;
            throw new ZygoteStartFailedEx("connect failed");                 
        }
    }

ActivityManagerService终于向Zygote发送请求了。请求的参数中有一个字符串,它的值是“android.app.ActivityThread”。现在该回到Zygote处理请求那块去看看了

有求必应之响应请求

runSelectLoopMode
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

/**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     *
     * @throws MethodAndArgsCaller in a child process when a main() should
     * be executed.
     */
    private static void runSelectLoopMode() throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList();
        ArrayList<ZygoteConnection> peers = new ArrayList();
        FileDescriptor[] fdArray = new FileDescriptor[4];

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        while (true) {
            int index;

            /*
             * Call gc() before we block in select().
             * It's work that has to be done anyway, and it's better
             * to avoid making every child do it.  It will also
             * madvise() any free memory as a side-effect.
             *
             * Don't call it every time, because walking the entire
             * heap is a lot of overhead to free a few hundred bytes.
             */
            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }


            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done;
                  //调用ZygoteConnection的runOnce
                done = peers.get(index).runOnce();

                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }

每当有请求数据发来时,Zygote都会调用ZygoteConnection的runOnce函数
来看看它的runOnce函数
frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

/**
     * Reads one start command from the command socket. If successful,
     * a child is forked and a {@link ZygoteInit.MethodAndArgsCaller}
     * exception is thrown in that child while in the parent process,
     * the method returns normally. On failure, the child is not
     * spawned and messages are printed to the log and stderr. Returns
     * a boolean status value indicating whether an end-of-file on the command
     * socket has been encountered.
     *
     * @return false if command socket should continue to be read from, or
     * true if an end-of-file has been encountered.
     * @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main()
     * method in child process
     */
    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
        //读取SS发送过来的参数
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            closeSocket();
            return true;
        }

        if (args == null) {
            // EOF reached.
            closeSocket();
            return true;
        }

        /** the stderr of the most recent request, if avail */
        PrintStream newStderr = null;

        if (descriptors != null && descriptors.length >= 3) {
            newStderr = new PrintStream(
                    new FileOutputStream(descriptors[2]));
        }

        int pid;

        try {
            parsedArgs = new Arguments(args);

            applyUidSecurityPolicy(parsedArgs, peer);
            applyDebuggerSecurityPolicy(parsedArgs);
            applyRlimitSecurityPolicy(parsedArgs, peer);
            applyCapabilitiesSecurityPolicy(parsedArgs, peer);

            int[][] rlimits = null;

            if (parsedArgs.rlimits != null) {
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
            }
   //根据函数名,可知Zygote又分裂出了一个子进程。
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, parsedArgs.debugFlags, rlimits);
        } catch (IllegalArgumentException ex) {
            logAndPrintError (newStderr, "Invalid zygote arguments", ex);
            pid = -1;
        } catch (ZygoteSecurityException ex) {
            logAndPrintError(newStderr,
                    "Zygote security policy prevents request: ", ex);
            pid = -1;
        }

        if (pid == 0) {
            // in child
              //子进程处理,这个子进程是不是我们要创建的Activity对应的子进程呢?
            handleChildProc(parsedArgs, descriptors, newStderr);
            // should never happen
            return true;
        } else { /* pid != 0 */
            // in parent...pid of < 0 means failure
             //zygote进程
            return handleParentProc(pid, descriptors, parsedArgs);
        }
    }

看看新创建的子进程在handleChildProc中做了些什么
handleChildProc

/**
     * Handles post-fork setup of child proc, closing sockets as appropriate,
     * reopen stdio as appropriate, and ultimately throwing MethodAndArgsCaller
     * if successful or returning if failed.
     *
     * @param parsedArgs non-null; zygote args
     * @param descriptors null-ok; new file descriptors for stdio if available.
     * @param newStderr null-ok; stream to use for stderr until stdio
     * is reopened.
     *
     * @throws ZygoteInit.MethodAndArgsCaller on success to
     * trampoline to code that invokes static main.
     */
    private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, PrintStream newStderr)
            throws ZygoteInit.MethodAndArgsCaller {

        /*
         * First, set the capabilities if necessary
         */

        if (parsedArgs.uid != 0) {
            try {
                ZygoteInit.setCapabilities(parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IOException ex) {
                Log.e(TAG, "Error setting capabilities", ex);
            }
        }

        /*
         * Close the socket, unless we're in "peer wait" mode, in which
         * case it's used to track the liveness of this process.
         */

        if (parsedArgs.peerWait) {
            try {
                ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);
                sPeerWaitSocket = mSocket;
            } catch (IOException ex) {
                Log.e(TAG, "Zygote Child: error setting peer wait "
                        + "socket to be close-on-exec", ex);
            }
        } else {
            closeSocket();
            ZygoteInit.closeServerSocket();
        }

        if (descriptors != null) {
            try {
                ZygoteInit.reopenStdio(descriptors[0],
                        descriptors[1], descriptors[2]);

                for (FileDescriptor fd: descriptors) {
                    ZygoteInit.closeDescriptor(fd);
                }
                newStderr = System.err;
            } catch (IOException ex) {
                Log.e(TAG, "Error reopening stdio", ex);
            }
        }
//根据传入的参数设置新进程的一些属性
//SS发来的参数中有“--runtime-init“,所以parsedArgs.runtimeInit为true。
        if (parsedArgs.runtimeInit) {
            RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        } else {
            ClassLoader cloader;

            if (parsedArgs.classpath != null) {
                cloader
                    = new PathClassLoader(parsedArgs.classpath,
                    ClassLoader.getSystemClassLoader());
            } else {
                cloader = ClassLoader.getSystemClassLoader();
            }

            String className;
            try {
                className = parsedArgs.remainingArgs[0];
            } catch (ArrayIndexOutOfBoundsException ex) {
                logAndPrintError (newStderr,
                        "Missing required class name argument", null);
                return;
            }
            String[] mainArgs
                    = new String[parsedArgs.remainingArgs.length - 1];

            System.arraycopy(parsedArgs.remainingArgs, 1,
                    mainArgs, 0, mainArgs.length);

            try {
                ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
            } catch (RuntimeException ex) {
                logAndPrintError (newStderr, "Error starting. ", ex);
            }
        }
    }

RuntimeInit.java
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

/**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in finishInit()
     * were rationalized with Zygote startup.<p>
     *
     * Current recognized args:
     * <ul>
     *   <li> --nice-name=<i>nice name to appear in ps</i>
     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
     * </ul>
     *
     * @param argv arg strings
     */
    public static final void zygoteInit(String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        // TODO: Doing this here works, but it seems kind of arbitrary. Find
        // a better place. The goal is to set it up for applications, but not
        // tools like am.
        //重定向标准输出和错误输出
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

        commonInit();
        //下面这个函数为native函数,最终会调用AppRuntime的onZygoteInit,在那个函数中

//建立了和Binder的关系
        zygoteInitNative();

        int curArg = 0;
        for ( /* curArg */ ; curArg < argv.length; curArg++) {
            String arg = argv[curArg];

            if (arg.equals("--")) {
                curArg++;
                break;
            } else if (!arg.startsWith("--")) {
                break;
            } else if (arg.startsWith("--nice-name=")) {
                String niceName = arg.substring(arg.indexOf('=') + 1);
                Process.setArgV0(niceName);
            }
        }

        if (curArg == argv.length) {
            Log.e(TAG, "Missing classname argument to RuntimeInit!");
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main
        
        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];

        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
         //最终还是调用invokeStaticMain函数,这个函数我们已经见识过了。
        invokeStaticMain(startClass, startArgs);
    }

Zygote分裂子进程后,自己将在handleParentProc中做一些扫尾工作,然后继续等待请求进行下一次分裂。
这个android.app.ActivityThread类,实际上是Android中apk程序所对应的进程,它的main函数就是apk程序的main函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值