Android系统启动过程分析

主要流程

简化流程图

init进程启动过程

init进程是Android系统中用户空间的第一个进程。进程号为1。

引入init进程

第一步

当电源按下时引导芯片代码从预定的地方(固化为ROM中)开始执行。加载引导程序BootLoaderRAM中执行。

第二步

BootLoader是在Android操作系统开始运行前的一个小程序,主要作用是把系统OS拉起来运行。

第三步

当内核完成系统设置后,在系统文件中寻找init.rc文件,并启动init进程。

启动init进程就会执行它的入口函数main,文件路径为:system/core/init/init.cpp

int main(int argc, char** argv) {
    ......
    if (is_first_stage) {
        boot_clock::time_point start_time = boot_clock::now();
        umask(0);
        //创建和挂载启动所需要的文件目录
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        chmod("/proc/cmdline", 0440);
        gid_t groups[] = { AID_READPROC };
        setgroups(arraysize(groups), groups);
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
        ......
    }
    ......
    //对属性服务进行初始化
    property_init();
    ......

    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    if (epoll_fd == -1) {
        PLOG(ERROR) << "epoll_create1 failed";
        exit(1);
    }
    //用于设置子进程信号处理函数,如果子进程异常退出,init进程会调用该函 
    //数中设置的信号处理函数进行处理。
    signal_handler_init();
    ......
    //启动属性服务
    start_property_service();
    ......
    if (bootscript.empty()) {
        //解析init.rc配置文件
        parser.ParseConfig("/init.rc");
        parser.set_is_system_etc_init_loaded(
                parser.ParseConfig("/system/etc/init"));
        parser.set_is_vendor_etc_init_loaded(
                parser.ParseConfig("/vendor/etc/init"));
        parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
    } 
    ......
    while (true) {
        ......
        if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            am.ExecuteOneCommand();
        }
        if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            //重启死去的服务
            restart_processes();
        }
        ......
    }
    return 0;
}

从上述代码中可以看出,init进程主要做了三件事:

  • 创建和挂载启动所需的文件目录。

启动挂载了tmpfs、devpts、proc、sysfs和selinuxfs共5种文件系统,这些是系统运行时目录,也就是说只有在系统运行的时候才会存在。

  • 初始化和启动属性服务。

属性服务类似Windows平台上的注册表管理器,注册表中以key-value的形式来记录用户、软件的一些使用信息。即使系统或软件重启,也能够根据之前注册表中的记录,进行相应的初始化工作。

  • 解析init.rc文件,创建Zygote进程。

该文件的路径为:system/core/rootdir/init.rc。它是一个非常重要的配置文件,是由Android初始化语言编写的脚本。Android8.0对该文件进行来拆分,每个服务对应一个rc文件,启动Zygote的脚本在init.zygoteXX.rc中定义,代表多少位处理器。这里以64位为例。

system/core/rootdir/init.zygote64.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc
    socket zygote 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进程的创建,所以只贴出了init.rc文件中的Serivice类型的语句,省略了其他语句;这是由Android初始化语言编写的。它的格式如下:
service <name> <pathname> [ <argument> ]* //名字 执行程序路径 传递参数
< option > //修饰词,影响什么时候启动,如何启动service。
< option >
......
上面的代码的含义就是:通知init进程创建名为zygote的进程,这个进程的执行路径为:/system/bin/app/_process64,其后面的代码是传递给app_process64的参数。class main指的是zygoteclassnamemain

init.rc中的Service类型的语句有相应的类来进行解析,Service语句采用ServiceParser来进行解析,该实现代码在system/core/init/service.app中,代码在这不再贴出,大概的解析过程就是:根据参数创建出Service对象,然后根据选项域中的内容填充Service对象,最后将该对象加入vector类型的Service链表中。

init.rc中有如下代码:

......
on nonencrypted
    class_start main
    class_start late_start
......

class_start是Android初始化语言中的Command类型的语句,对应的函数为do_class_start含义就是启动classname为main的Service。,从上述代码我们知道zygoteclassnamemain。

do_class_start函数是在system/core/bin/builtins.cpp中,代码如下:

static int do_class_start(const std::vector<std::string>& args) {
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}

ForEachServiceInClass函数会遍历Service链表,找到classnamemainZygote,并执行StartIfNotDisabled ()函数。

StartIfNotDisabled ()函数的代码是在system/core/init/service.cpp中定义的,代码如下:

bool Service::StartIfNotDisabled() {
    if (!(flags_ & SVC_DISABLED)) {
        return Start();
    } else {
        flags_ |= SVC_DISABLED_START;
    }
    return true;
}

如果Service没有在其对应的rc文件中设置disabled选项,就会执行Start()函数,Zygote对应的文件没有设置disabled选项

Start()函数:system/core/init/service.cpp

bool Service::Start() { 
    flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
    //如果已运行,直接返回
    if (flags_ & SVC_RUNNING) {
        return false;
    }
    ......
    struct stat sb;
    //判断需要启动的Service对应的执行文件是否存在,存在才会执行。
    if (stat(args_[0].c_str(), &sb) == -1) {
        PLOG(ERROR) << "cannot find '" << args_[0] << "', disabling '" << name_ << "'";
        flags_ |= SVC_DISABLED;
        return false;
    }
    ......
    pid_t pid = -1;
    if (namespace_flags_) {
        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
    } else {
        //如果没有启动,调用fork函数创建子进程
        pid = fork();
    }

    if (pid == 0) {
        umask(077);
        ......
        //调用execve函数,子进程就会被启动
        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
            PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
        }
        _exit(127);
    }
    ......
    return true;
}

调用execve 函数,子进程就会被启动,就是执行对应的main函数Zygote的执行路径为:system/bin/app_process64,对应的文件为app_main.cpp

frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const 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.");
    }
}

调用runtime.start函数就启动了Zygote进程

Zygote进程

Android系统中,DVM和ART、应用程序进程以及运行系统的关键服务SystemServer进程都是有Zygote进程创建的,我们也称它为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动的时候会创建DVM或者ART,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM或者ART的实例副本(也就是说一个Android应用程序对应这一个DVM或者ART)。

Zygote进程都是通过fock自身来创建子进程的,这样Zygote进程以及子进程都会进入app_main.cppmain函数,所以在上述代码中先区分来当前运行在哪个进程中。运行Zygote进程就会执行AndroidRuntime.start函数

frameworks/base/core/jni/AndroidRuntime.cpp代码如下:

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ......
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动Java虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);
    //为JVM注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    ......
    //从app_main传过来的参数classname值为:“com.android.internal.os.ZygoteInit”
    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);
    }
    //将classname的“.”替换成“/”
    char* slashClassName = toSlashClassName(className);
    //找到ZygoteInit
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
        //找到ZygoteInit的main函数
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            //通过JNI调用ZygoteInit的main函数
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

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

上述代码最后会调用ZygoteInitmain方法,该方法是由Java语言编写的,当前的运行逻辑在Native中,这就需要通过JNI来调用Java。这样Zygote就从Native层近入了Java框架层

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.javamain方法代码如下:

public static void main(String argv[]) {
    ......
    try {
        ......
        //创建一个Server端的socket,socketName = “zygote”
       //在这个socket上会等待AMS的请求
        zygoteServer.registerServerSocket(socketName);
        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();
        }
        //启动SystemServer进程
        if (startSystemServer) {
            startSystemServer(abiList, socketName, zygoteServer);
        }
        //等待AMS请求,里面是一个while(true)循环
        zygoteServer.runSelectLoop(abiList);
        zygoteServer.closeServerSocket();
    }......
}

该方法中主要做了4件事:
1.创建一个Server端的socket(LocalServerSocket)。
2.预加载类和资源。
3.启动SystemServer进程。
4.等待AMS请求创建新的应用程序进程。

从上面的代码我们看出Zygote进程主要做了如下几件事情:

  • 1.创建Java虚拟机并为Java虚拟机注册JNI方法。
  • 2.通过JNI调用ZygoteInitmain函数进入Zygote的Java框架层。
  • 3.通过registerServerSocket 方法创建服务端Socket,并通过runSelectLoop 方法等待AMS的请求来创建新的应用程序进程。
  • 4.启动SystemServer进程。

SystemServer进程

SystemServer进程主要用于创建系统服务,AMS、WMS、PMS都是由它来创建的。从上面得知通过调用ZygoteInitstartSystemServer 方法来启动SystemServer进程,下面就看一下该方法的代码:

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
        throws Zygote.MethodAndArgsCaller, RuntimeException {
    ......
    //创建args数组,该数组用来保存启动SystemServer的启动参数
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;
    int pid;
    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
        //创建一个子进程,也就是SystemServer进程
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
    //当前代码运行在子进程中,也就是SystemServer进程
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        //SystemServer进程复制了Zygote进程的地址空间,因此也会得到Zygote创建的Socket。
        //该Socket对SystemServer进程没有用,所以要关闭。
        zygoteServer.closeServerSocket();
        //处理SystemServer进程
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

从上面代码可以看出,SystemServer进程的用户id和用户组id被设置为1000,并且拥有1001~1010、1018、1021、1032、3001~3010的权限;进程名字为system_server;启动的类名为:com.android.server.SystemServer

创建出SystemServer进程之后就会在该进程调用ZygoteInit.handleSystemServerProcess 方法,下面看一下该方法的代码:

private static void handleSystemServerProcess(
        ZygoteConnection.Arguments parsedArgs)
        throws Zygote.MethodAndArgsCaller {
    ......
    if (parsedArgs.invokeWith != null) {
      ......
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            //创建PathClassLoader
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
            Thread.currentThread().setContextClassLoader(cl);
        }
        //调用zygoteInit方法
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}

public static final void zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();
    RuntimeInit.commonInit();
    //启动Binder线程池
    ZygoteInit.nativeZygoteInit();
    //执行SystemServer的main方法
    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit方法中创建了Binder线程池,这样SystemServer进程就可以使用Binder于其他进程进行通信了。

创建Binder线程池后会调用RuntimeInit.applicationInit方法,下面就接着看下该方法的代码:
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    ......
    // Remaining arguments are passed to the start class's static main
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    Class<?> cl;
    try {
        //通过反射得到SystemServer类
        cl = Class.forName(className, true, classLoader);
    }......
    Method m;
    try {
        //找到SystemServer的main方法
        m = cl.getMethod("main", new Class[] { String[].class });
    }......
    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.
     */
    throw new Zygote.MethodAndArgsCaller(m, argv);
}

通过反射得到SystemServer,className的值就是上面提到的com.android.server.SystemServer,然后再找到main方法,最后将main方法传入Zygote .MethodAndArgsCaller异常中并抛出该异常。捕获该异常的代码在ZygoteInit.main方法中,该main方法会调用SystemServermain方法

那为什么不直接在invokeStaticMain方法中调用呢?而是在异常捕获中调用?

原因是异常处理会清楚所有设置过程中需要的堆栈帧,让SystemServermain方法看起来像是SystemServer进程的入口。(在Zygote
启动SystemServer进程之后,SystemServer进程做了很多准备工作,这些工作都是在main方法调用之前做的。)

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.javamain方法代码:

public static void main(String argv[]) {
    ......
    try {
    ......
    //捕获MethodAndArgsCaller异常
    } catch (Zygote.MethodAndArgsCaller caller) {
        caller.run();
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        zygoteServer.closeServerSocket();
        throw ex;
    }
}

在异常处理中直接调用Zygote.MethodAndArgsCallerrun方法,可以看出MethodAndArgsCallerZygote的静态内部类。

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    ......
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
    ......
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        }......
    }
}

此处的mMethod就是SystemServermain方法

这样就进入了SystemServermain方法

/frameworks/base/services/java/com/android/server/SystemServer.java

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

private void run() {
    try {
        ......
        //创建Looper
        Looper.prepareMainLooper();
        //加载动态库“libandroid_servers.so”
        System.loadLibrary("android_servers");
        performPendingShutdown();
        //创建系统的上下文Context
        createSystemContext();
        // 创建SystemServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }
    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        //启动引导服务
        startBootstrapServices();
        //启动核心服务
        startCoreServices();
        //启动其他服务
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    }......
}

通过上面可以看出系统服务分为三种:
1.引导服务。
2.核心服务。
3.其他服务。

private void startBootstrapServices() {
    ......
    Installer installer = mSystemServiceManager.startService(Installer.class);
    ......
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    ......
   //需要注意的是 ActivityManagerService.Lifecycle实现了SystemService
    mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
    ......
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    ......
    //在该方法中会把ActivityManagerService添加到ServiceManager中
    mActivityManagerService.setSystemProcess();
    ......
}
private void startCoreServices() {
    ......
    mSystemServiceManager.startService(DropBoxManagerService.class);
    traceEnd();
    ......
    mSystemServiceManager.startService(BatteryService.class);
    ......
}
private void startOtherServices() {
    ......
    mSystemServiceManager.startService(KeyChainSystemService.class);
    ......
    mSystemServiceManager.startService(TelecomLoaderService.class);
    ......
}

部分服务表:

引导服务 作用
Installer 系统安装APK时的一个服务,启动完成Installer服务之后才能启动其他的服务
ActivityManagerService 负责四大组件的启动、切换和调度
PowerManagerService 计算系统中和Power相关的计算,然后决策系统应该如何反应
LightsService 管理和显示背光LED
DisplayManagerService 用来管理所有显示的设备
UserManagerService 多用户模式管理
SensorService 为系统提供各种感应器服务
PackageManagerService 用来对APK进行安、解析、删除、卸载等操作
...... .....
核心服务
DropBoxManagerService 用于生成和管理系统运行时的一些日志文件
BatteryService 管理电池相关的服务
UsageStatsService 收集用户使用每一个app的频率、使用时长
WebViewUpdateService WebView更新服务
其他服务
CameraService 摄像头相关服务
AlarmManagerService 全局定时器管理服务
InputManagerService 管理输入事件
WindowManagerService 窗口管理服务
VrManagerService VR模式管理服务
BluetoothService 蓝牙管理服务
NotificationManagerService 通知管理服务
DeviceStorageMonitorService 存储相关管理服务
LocationManagerService 定位管理服务
AudioService 音频相关管理服务
...... ......

我们从上面看出相关的服务一种是通过SystemServiceManagerstartService方法来启动的;另一种是直接调用服务的main方法,比如:PackageManagerService。下面分别看一下这两种方式的代码实现:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public class SystemServiceManager {
    ......
    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
    ......
    //startService方法有几个重载,最终都会调用该方法
    public void startService(@NonNull final SystemService service) {
        //注册服务
        mServices.add(service);
        // Start it.
        long time = System.currentTimeMillis();
        try {
            //调用服务自身的onStart方法
            service.onStart();
        }......
    }
}
public abstract class SystemService {
    ......
}

先将服务添加到mService中,它是一个存储SystemService类型的ArrayList,这样就完成来该服务的注册工作。然后调用服务自身的onStart()方法来启动服务。由SystemServiceManager创建并启动的服务,都是继承了SystemService,但是并没有实现IBinder,所以是不可以进行Binder通信的,也就是由它管理的服务是用于进程内部通信的。

/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender {
    ......
    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        PackageManagerServiceCompilerMapping.checkProperties();
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        m.enableSystemUserPackages();
        //注册
        ServiceManager.addService("package", m);
        return m;
    }
    ......
}

创建对象后添加到ServiceManager中,它是用来管理系统中各种Service的,由它管理的服务都实现了IBinder,所以在ServiceManager中注册的服务是用于进程间通信的:用于系统C/S架构中的Binder通信机制。客户端要使用某个Service,需要先到ServiceManager中查询Service的信息,然后根据该信息与Service所在的Server进程建立通信,这样客户端就可以使用Service了。

从上面的代码我们看出SystemServer进程主要做了如下几件事情:

  • 1.启动Binder线程池,这样就可以与其他进程进行通信了。
  • 2.创建SystemServiceManager,用于对系统其他服务进行创建、启动和声明周期管理。
  • 3.启动各种系统服务。

SystemServer进程Zygote进程fork的第一个进程。其中WindowManagerService、ActivityManagerService、PackageManagerService等重要的可以binder通信的服务都运行在这个SystemServer进程

Launcher启动过程

系统启动的最后一步就是启动一个应用程序来显示系统中已经安装的应用程序,这个程序就叫做Launcher。它在启动过程中会请求PackagerMangerService返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上。这样用户就可以通过点击快捷图标来启动相应的应用程序了。

在上面SystemServer进程分析过程中,我们知道ActivityManagerService(简称:AMS)是负责四大组件的启动、切换和调度的。系统桌面本身也是一个Activity,所以Launcher的启动是在AMS中进行的,启动Launcher的入口是AMSsystemReady方法。该方法是在SystemServerstartOtherServices方法中被调用的,下面就看一下该方法的实现代码:

private void startOtherServices(){
    ......
    mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        traceBeginAndSlog("StartActivityManagerReadyPhase");
        mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);
        traceEnd();
        traceBeginAndSlog("StartObservingNativeCrashes");
        try {
            mActivityManagerService.startObservingNativeCrashes();
        } catch (Throwable e) {
            reportWtf("observing native crashes", e);
        }
        traceEnd();
    ......
}

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
    ......
    synchronized (this) {
        ......
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
        mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
        ......
    }
}

该方法中调用了ActivityStackSupervisorresumeFocusedStackTopActivityLocked()方法

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    ......
    return false;
}

ActivityStack是用来描述Activity堆栈的。

最后经过重重调用,最终会调用AMSstartHomeActivityLocked方法

boolean startHomeActivityLocked(int userId, String reason) {
    //判断系统的运行模式和mTopAction的值
    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
            && mTopAction == null) {
        return false;
    }
    获取Luncher启动所需要的Intent
    Intent intent = getHomeIntent();
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid, true);
        if (app == null || app.instr == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
            final String myReason = reason + ":" + userId + ":" + resolvedUserId;
            //启动Luncher
            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }
    return true;
}

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

mFactoryTest代表系统运行模式,运行模式有三种:非工厂模式、低级工厂模式和高级工厂模式mTopAction表示第一个被启动Activity组件的Action,它的默认值为:Intent.ACTION_MAIN

getHomeIntent方法中,如果mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL(低级工厂模式)Category的值为:Intent.CATEGORY_HOME。也就是说如果系统运行模式不是低级工厂模式那么:
action = Intent.ACTION_MAIN
category = Intent.CATEGORY_HOME
而服务这个描述的应用程序就是Luncher,因为LuncherAndroidManifest文件中的intent-filter匹配了这两个值:

/packages/apps/Launcher3/AndroidManifest.xml

<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
......
<application
    ......
    <activity
        android:name="com.android.launcher3.Launcher"
        android:launchMode="singleTask"
        android:clearTaskOnLaunch="true"
        android:stateNotNeeded="true"
        android:windowSoftInputMode="adjustPan"
        android:screenOrientation="unspecified"
        android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
        android:resizeableActivity="true"
        android:resumeWhilePausing="true"
        android:taskAffinity=""
        android:enabled="true">
        <intent-filter>
            //匹配规则
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.MONKEY"/>
            <category android:name="android.intent.category.LAUNCHER_APP" />
        </intent-filter>
    </activity>
    ......
</application>
</manifest>

Luncher完成启动后,作为桌面它会显示应用程序图标。

参考《Android进阶解密》

实战

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容