• 你想要找的activity知识都在这里了
  • 一份超详细的Fragment知识总结
  • FragmentManager与FragmentTransaction底层实现
  • Android 启动过程

todo: 目前只是一个粗版,在写 ActivityManagerService 过程中,会重新梳理并补充时序图、整体结构、各种细节点的。

init.rc

init 是 Android 第一个被启动的进程,init 的 PID 的值是 0,它通过解析 init.rc 脚本来构建出系统的初始运行形态,初始化程序 init.c 就是根据 init.rc 文件来初始化 android 内核驱动的,而其他 Android 系统服务程序大多都是在这个 init.rc 脚本中描述并被启动的,如:ServiceManager、Zygote、SystemService。

init.rc 规范参考 /system/core/init/Readme.txt ,init.rc 位于 system/core/rootdir/init,rc 。部分代码见下:

import /init.environ.rcimport /init.usb.rcimport /init.${     ro.hardware}.rcimport /vendor/etc/init/hw/init.${     ro.hardware}.rcimport /init.usb.configfs.rcimport /init.${     ro.zygote}.rc# Cgroups are mounted right before early-init using list from /etc/cgroups.jsonon early-init    # Disable sysrq from keyboard    write /proc/sys/kernel/sysrq 0    # Set the security context of /adb_keys if present.    restorecon /adb_keys    # Set the security context of /postinstall if present.    restorecon /postinstall    mkdir /acct/uid    # memory.pressure_level used by lmkd    chown root system /dev/memcg/memory.pressure_level    chmod 0040 /dev/memcg/memory.pressure_level    # app mem cgroups, used by activity manager, lmkd and zygote    mkdir /dev/memcg/apps/ 0755 system system    # cgroup for system_server and surfaceflinger    mkdir /dev/memcg/system 0550 system system    start ueventd    # Run apexd-bootstrap so that APEXes that provide critical libraries    # become available. Note that this is executed as exec_start to ensure that    # the libraries are available to the processes started after this statement.    exec_start apexd-bootstrap

Zygote

Zygote 也是由 init 解析 rc 脚本时启动的。Android 系统针对 32 位和 64 位机器加载不同的描述 Zygote.rc 脚本。

以 init.zygote32,rc 为例,代码见下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    class main    priority -20    user root    group root readproc reserved_disk    socket zygote stream 660 root system    socket usap_pool_primary stream 660 root system    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart audioserver    onrestart restart cameraserver    onrestart restart media    onrestart restart netd    onrestart restart wificond    writepid /dev/cpuset/foreground/tasks

从 zygote 的 path 可以看出,它所在的程序名叫 app_process。通过指定 zygote 参数,可以识别用户是否需要启动 zygote。

app_process

pp_process 的源码路径在 /frameworks/base/cmds/app_pocess 中,主函数 app_main.cpp 部分代码见下:

int main(int argc, char* const argv[]){         ...    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));    ...    while (i < argc) {             const char* arg = argv[i++];        if (strcmp(arg, "--zygote") == 0) {                 zygote = true;            niceName = ZYGOTE_NICE_NAME;        } else if (strcmp(arg, "--start-system-server") == 0) {                 startSystemServer = true;        } else if (strcmp(arg, "--application") == 0) {                 application = true;        } else if (strncmp(arg, "--nice-name=", 12) == 0) {                 niceName.setTo(arg + 12);        } else if (strncmp(arg, "--", 2) != 0) {                 className.setTo(arg);            break;        } else {                 --i;            break;        }    }    ...    if (zygote) {             runtime.start("com.android.internal.os.ZygoteInit", args, zygote);    } else if (className) {             runtime.start("com.android.internal.os.RuntimeInit", args, zygote);    } else {             fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");    }}

init.rc 指定 – zygote 选项,因而 app_process 将启动 “com.android.internal.os.ZygoteInit”, 并将进程别名改为 “zygote” 或 “zygote64” 。 之后 ZygoteInit 会运行在 Java 虚拟机上,因为 runtime 就是一个 AppRuntime 对象。

AppRuntime

源码位于 /frameworks/base/core/jni/AndroidRuntime.cpp ,部分代码见下:

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){         ...    /* start the virtual machine */    JniInvocation jni_invocation;    jni_invocation.Init(NULL);    JNIEnv* env;    if (startVm(&mJavaVM, &env, zygote) != 0) {             return;    }    onVmCreated(env);    /*     * Register android functions.     */    if (startReg(env) < 0) {             ALOGE("Unable to register all android natives\n");        return;    }    /*     * We want to call main() with a String array with arguments in it.     * At present we have two arguments, the class name and an option string.     * Create an array to hold them.     */    jclass stringClass;    jobjectArray strArray;    jstring classNameStr;    stringClass = env->FindClass("java/lang/String");    assert(stringClass != NULL);    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);    assert(strArray != NULL);    classNameStr = env->NewStringUTF(className);    assert(classNameStr != NULL);    env->SetObjectArrayElement(strArray, 0, classNameStr);    for (size_t i = 0; i < options.size(); ++i) {             jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());        assert(optionsStr != NULL);        env->SetObjectArrayElement(strArray, i + 1, optionsStr);    }    /*     * Start VM.  This thread becomes the main thread of the VM, and will     * not return until the VM exits.     */    char* slashClassName = toSlashClassName(className != NULL ? className : "");    jclass startClass = env->FindClass(slashClassName);    if (startClass == NULL) {             ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);        /* keep going */    } else {             jmethodID startMeth = env->GetStaticMethodID(startClass, "main",            "([Ljava/lang/String;)V");        if (startMeth == NULL) {                 ALOGE("JavaVM unable to find main() in '%s'\n", className);            /* keep going */        } else {                 env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0            if (env->ExceptionCheck())                threadExitUncaughtException(env);#endif        }    }    ...}

start 方法中的 startVm 方法会根据 android 属性来设置虚拟机的参数,onVmCreated 方法为虚拟机启动回调,startReg 方法来初始化 java 的 native 代码。虚拟机启动后会通过反射调用 ZygoteInit 的 main 方法。这里的 className 即在app_process 传入的 “com.android.internal.os.ZygoteInit”。

ZygoteInit

源码位于 /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java , 部分代码见下:

public static void main(String argv[]) {             ...        try {                 // Report Zygote start time to tron unless it is a runtime restart            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {                     MetricsLogger.histogram(null, "boot_zygote_init",                        (int) SystemClock.elapsedRealtime());            }            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,                    Trace.TRACE_TAG_DALVIK);            bootTimingsTraceLog.traceBegin("ZygoteInit");            RuntimeInit.enableDdms();            boolean startSystemServer = false;            String zygoteSocketName = "zygote";            String abiList = null;            boolean enableLazyPreload = false;            for (int i = 1; i < argv.length; i++) {                     if ("start-system-server".equals(argv[i])) {                         startSystemServer = true;                } else if ("--enable-lazy-preload".equals(argv[i])) {                         enableLazyPreload = true;                } else if (argv[i].startsWith(ABI_LIST_ARG)) {                         abiList = argv[i].substring(ABI_LIST_ARG.length());                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {                         zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());                } else {                         throw new RuntimeException("Unknown command line argument: " + argv[i]);                }            }            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);            if (abiList == null) {                     throw new RuntimeException("No ABI list supplied.");            }            // In some configurations, we avoid preloading resources and classes eagerly.            // In such cases, we will preload things prior to our first fork.            if (!enableLazyPreload) {                     bootTimingsTraceLog.traceBegin("ZygotePreload");                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                        SystemClock.uptimeMillis());                preload(bootTimingsTraceLog);                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                        SystemClock.uptimeMillis());                bootTimingsTraceLog.traceEnd(); // ZygotePreload            } else {                     Zygote.resetNicePriority();            }            ...            zygoteServer = new ZygoteServer(isPrimaryZygote);            if (startSystemServer) {                     Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the                // child (system_server) process.                if (r != null) {                         r.run();                    return;                }            }            Log.i(TAG, "Accepting command socket connections");            // The select loop returns early in the child process after a fork and            // loops forever in the zygote.            caller = zygoteServer.runSelectLoop(abiList);        } catch (Throwable ex) {                 Log.e(TAG, "System zygote died with exception", ex);            throw ex;        } finally {                 if (zygoteServer != null) {                     zygoteServer.closeServerSocket();            }        }        // We're in the child process and have exited the select loop. Proceed to execute the        // command.        if (caller != null) {                 caller.run();        }    }

如果 app_process 的调用参数 argv[] 不带有 “–enable-lazy-preload”,则会通过 preload(bootTimingsTraceLog) 方法直接预加载虚拟机运行时所需要的各类资源。具体代码如下:

    static void preload(TimingsTraceLog bootTimingsTraceLog) {             Log.d(TAG, "begin preload");        bootTimingsTraceLog.traceBegin("BeginPreload");        beginPreload();        bootTimingsTraceLog.traceEnd(); // BeginPreload        bootTimingsTraceLog.traceBegin("PreloadClasses");        preloadClasses();        bootTimingsTraceLog.traceEnd(); // PreloadClasses        bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");        cacheNonBootClasspathClassLoaders();        bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders        bootTimingsTraceLog.traceBegin("PreloadResources");        preloadResources();        bootTimingsTraceLog.traceEnd(); // PreloadResources        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");        nativePreloadAppProcessHALs();        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");        maybePreloadGraphicsDriver();        ...        Log.d(TAG, "end preload");        sPreloadComplete = true;    }

再回到 ZygoteInit main 主函数代码。我们通过 argv[] 参数以判断 startSystemServer 是否需要启动 System Server。通过创建 new ZygoteServer(isPrimaryZygote) 对象,来创建一个 Socket 接口,Socket 接口是通过文件描述符控制的,指定 Socket 名称可以在 system/core/rootdir 中找到,Socket 已绑定到 到/dev/sockets/目录中的文件系统。通过环境变量 ANDROID_SOCKET_< socketName > 获取。

    ZygoteServer(boolean isPrimaryZygote) {             mUsapPoolEventFD = Zygote.getUsapPoolEventFD();        if (isPrimaryZygote) {                 // PRIMARY_SOCKET_NAME: "zygote"            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);            mUsapPoolSocket =                    Zygote.createManagedSocketFromInitSocket(                            Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);        } else {                 // SECONDARY_SOCKET_NAME: "zygote_secondary"            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);            mUsapPoolSocket =                    Zygote.createManagedSocketFromInitSocket(                            Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);        }        fetchUsapPoolPolicyProps();        mUsapPoolSupported = true;    }

再回到 ZygoteInit main 主函数代码。接下来的 forkSystemServer 方法会创建一个新的进程来启动各种系统服务,此方法稍后再说。我们先来看下当下进程的 runSelectLoop 方法,这是一个死循环,除非 Zygote 退出或者出现异常,否则不会跳出循环。部分代码见下:

Runnable runSelectLoop(String abiList) {             ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();        socketFDs.add(mZygoteSocket.getFileDescriptor());        peers.add(null);        while (true) {                 fetchUsapPoolPolicyPropsWithMinInterval();            int[] usapPipeFDs = null;            StructPollfd[] pollFDs = null;            // Allocate enough space for the poll structs, taking into account            // the state of the USAP pool for this Zygote (could be a            // regular Zygote, a WebView Zygote, or an AppZygote).            if (mUsapPoolEnabled) {                     usapPipeFDs = Zygote.getUsapPipeFDs();                pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];            } else {                     pollFDs = new StructPollfd[socketFDs.size()];            }            ...            boolean usapPoolFDRead = false;            while (--pollIndex >= 0) {                     if ((pollFDs[pollIndex].revents & POLLIN) == 0) {                         continue;                }                if (pollIndex == 0) {                         // Zygote server socket                    ZygoteConnection newPeer = acceptCommandPeer(abiList);                    peers.add(newPeer);                    socketFDs.add(newPeer.getFileDescriptor());                } else if (pollIndex < usapPoolEventFDIndex) {                         // Session socket accepted from the Zygote server socket                    try {                             ZygoteConnection connection = peers.get(pollIndex);                        final Runnable command = connection.processOneCommand(this);                        ...                        }                     ...                } else {                         // Either the USAP pool event FD or a USAP reporting pipe.                    // If this is the event FD the payload will be the number of USAPs removed.                    // If this is a reporting pipe FD the payload will be the PID of the USAP                    // that was just specialized.                    long messagePayload = -1;                    try {                             byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];                        int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);                        if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {                                 DataInputStream inputStream =                                    new DataInputStream(new ByteArrayInputStream(buffer));                            messagePayload = inputStream.readLong();                        } else {                                 Log.e(TAG, "Incomplete read from USAP management FD of size "                                    + readBytes);                            continue;                        }                    } catch (Exception ex) {                             if (pollIndex == usapPoolEventFDIndex) {                                 Log.e(TAG, "Failed to read from USAP pool event FD: "                                    + ex.getMessage());                        } else {                                 Log.e(TAG, "Failed to read from USAP reporting pipe: "                                    + ex.getMessage());                        }                        continue;                    }                    if (pollIndex > usapPoolEventFDIndex) {                             Zygote.removeUsapTableEntry((int) messagePayload);                    }                    usapPoolFDRead = true;                }            }            // Check to see if the USAP pool needs to be refilled.            if (usapPoolFDRead) {                     int[] sessionSocketRawFDs =                        socketFDs.subList(1, socketFDs.size())                                .stream()                                .mapToInt(fd -> fd.getInt$())                                .toArray();                final Runnable command = fillUsapPool(sessionSocketRawFDs);                if (command != null) {                         return command;                }            }        }    }

我们从 mZygoteSocket.getFileDescriptor() 获取上面 Socket 的文件描述符,并添加到 ArrayList< FileDescriptor > 的集合里,这意味着 zygote 中不光只有一个 Socket 产生。当 index == 0 时,表示没有可处理的连接,会产生一个新的 ZygoteConnection,等待来自客户端的连接。当 index > 0 时,说明已建立的 Socket 连接中有来自客户端的数据需要处理,具体逻辑见 processOneCommand 方法,在这里通过 forkAndSpecialize 方法,为每个新启动的应用程序生成自己独立的进程,并在 handleChildProc 方法中运行应用程序本身的代码:

Runnable processOneCommand(ZygoteServer zygoteServer) {             ...        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);        try {                 if (pid == 0) {                     // in child                zygoteServer.setForkChild();                zygoteServer.closeServerSocket();                IoUtils.closeQuietly(serverPipeFd);                serverPipeFd = null;                return handleChildProc(parsedArgs, descriptors, childPipeFd,                        parsedArgs.mStartChildZygote);            } else {                     // In the parent. A pid < 0 indicates a failure and will be handled in                // handleParentProc.                IoUtils.closeQuietly(childPipeFd);                childPipeFd = null;                handleParentProc(pid, descriptors, serverPipeFd);                return null;            }        } finally {                 IoUtils.closeQuietly(childPipeFd);            IoUtils.closeQuietly(serverPipeFd);        }    }

再回到 ZygoteInit main 主函数代码。在 forkSystemServer 方法内通过 forkSystemServer 方法创建了一个新的进程,其中 “–setuid=1000” 代表进程 ID,“–nice-name=system_server”代表进程名称。而这个进程接下来会执行 handleSystemServerProcess 方法,来启动支撑系统运行的 System Server。

    private static Runnable forkSystemServer(String abiList, String socketName,            ZygoteServer zygoteServer) {             ...        /* 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,1018,1021,1023,"                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",                "--capabilities=" + capabilities + "," + capabilities,                "--nice-name=system_server",                "--runtime-args",                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,                "com.android.server.SystemServer",        };        ZygoteArguments parsedArgs = null;        int pid;        try {                 parsedArgs = new ZygoteArguments(args);            Zygote.applyDebuggerSystemProperty(parsedArgs);            Zygote.applyInvokeWithSystemProperty(parsedArgs);            boolean profileSystemServer = SystemProperties.getBoolean(                    "dalvik.vm.profilesystemserver", false);            if (profileSystemServer) {                     parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;            }            /* Request to fork the system server process */            pid = Zygote.forkSystemServer(                    parsedArgs.mUid, parsedArgs.mGid,                    parsedArgs.mGids,                    parsedArgs.mRuntimeFlags,                    null,                    parsedArgs.mPermittedCapabilities,                    parsedArgs.mEffectiveCapabilities);        } catch (IllegalArgumentException ex) {                 throw new RuntimeException(ex);        }        /* For child process */        if (pid == 0) {                 if (hasSecondZygote(abiList)) {                     waitForSecondaryZygote(socketName);            }            zygoteServer.closeServerSocket();            return handleSystemServerProcess(parsedArgs);        }        return null;    }

在 handleSystemServerProcess 方法内,当 parsedArgs.mInvokeWith == null 时,会执行 ZygoteInit.zygoteInit 方法。

    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {             ...        if (parsedArgs.mInvokeWith != null) {                 String[] args = parsedArgs.mRemainingArgs;            ...            WrapperInit.execApplication(parsedArgs.mInvokeWith,                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,                    VMRuntime.getCurrentInstructionSet(), null, args);            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");        } else {                 createSystemServerClassLoader();            ClassLoader cl = sCachedSystemServerClassLoader;            if (cl != null) {                     Thread.currentThread().setContextClassLoader(cl);            }            /*             * Pass the remaining arguments to SystemServer.             */            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,                    parsedArgs.mRemainingArgs, cl);        }        /* should never reach here */    }

这是 zygoteInit 的逻辑,redirectLogStreams 关闭 system.out 和 system.err ,并重定向到 android log。commonInit 处理了通用部分的初始化操作,nativeZygoteInit 是本地初始化函数,负责本地系统服务的启动,而在 JNI 机制中, Native 函数在 Java 层会有一个声明,然后在本地层得到真正的实现。可见下文的 SystemServer().run() 方法内的 System.loadLibrary(“android_servers”) :

 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {             if (RuntimeInit.DEBUG) {                 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");        }        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");        RuntimeInit.redirectLogStreams();        RuntimeInit.commonInit();        ZygoteInit.nativeZygoteInit();        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);    }

在 applicationInit 方法中,startClass 即上文说的 forkSystemServer 创建服务进程时的 args 内的 “com.android.server.SystemServer”,findStaticMain 方法将会反射调用 startClass 的 main 方法。

    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {             ...        // Remaining arguments are passed to the start class's static main        return findStaticMain(args.startClass, args.startArgs, classLoader);    }    protected static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {             Class<?> cl;        try {                 cl = Class.forName(className, true, classLoader);        } catch (ClassNotFoundException ex) {                 throw new RuntimeException(                    "Missing class when invoking static main " + className,                    ex);        }        Method m;        try {                 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.         */        return new MethodAndArgsCaller(m, argv);    }

这是 SystemServer 的 main 主函数,也就是 applicationInit 反射调用的方法,它又会直接调用 SystemServer().run() 方法来实现 java 层系统服务的启动。

    public static void main(String[] args) {             new SystemServer().run();    }

在 run 方法中,准备主循环体,加载本地服务库到内存,并初始化本地服务,启动各种类型的 system server,通过 Looper.loop 进入长循环中,并依托 nativeZygoteInit 启动的 Binder 服务接受和处理外界请求。

    private void run() {             try {                 ...            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {                     Slog.w(TAG, "System clock is before 1970; setting to 1970.");                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);            }            ...            Looper.prepareMainLooper();            Looper.getMainLooper().setSlowLogThresholdMs(                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);            // Initialize native services.            System.loadLibrary("android_servers");            // Debug builds - allow heap profiling.            if (Build.IS_DEBUGGABLE) {                     initZygoteChildHeapProfiling();            }            // Check whether we failed to shut down last time we tried.            // This call may not return.            performPendingShutdown();            // Initialize the system context.            createSystemContext();            // Create the system service manager.            mSystemServiceManager = new SystemServiceManager(mSystemContext);            mSystemServiceManager.setStartInfo(mRuntimeRestart,                    mRuntimeStartElapsedTime, mRuntimeStartUptime);            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);            // Prepare the thread pool for init tasks that can be parallelized            SystemServerInitThreadPool.get();        } finally {                 traceEnd();  // InitBeforeStartServices        }        // Start services.        try {                 traceBeginAndSlog("StartServices");            startBootstrapServices();            startCoreServices();            startOtherServices();            SystemServerInitThreadPool.shutdown();        } catch (Throwable ex) {                 Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;        } finally {                 traceEnd();        }        ...        // Loop forever.        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");    }

参考
1、林学森,深入理解Android内核设计思想:人民邮电出版社

更多相关文章

  1. Android完美解决输入框EditText隐藏密码打勾显示密码问题
  2. Android有用代码片段(二)
  3. Zxing 竖屏切换 android
  4. Android(安卓)总结:进阶之路(资源与方法)
  5. Android面试复习(Android篇一)
  6. Android(安卓)按钮点击事件监听的3重方式
  7. Instrumentation 框架简介
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. 一键切换Android应用环境(Environment Swi
  2. Android(安卓)UI 限定字数 单独一行
  3. Android静态注册广播receiver检测WIFI连
  4. Android(安卓)ListView那些事
  5. 用ARM DS-5进行android linux开发
  6. 更新Anadroid SDK Tooks之后,Eclipse提示N
  7. Android实现伴奏录音合成MP3
  8. 关于android的listview的数据解析和性能
  9. Android中xml中shape的属性助记
  10. Android中fragment A里面点击button跳转