Android 系统启动分析

文章目录

        • 1、简述
        • 2、细节概要
          • 总体流程
          • Q1: init进程是什么?init进程启动?既然init进程这么重要那么init究竟做了什么呢?
          • Q2: 属性服务作用特性
          • init进程启动总结
          • Q3: zygote是什么?zygote进程启动?作用?
          • Zygote进程启动总结
          • 创建服务端的socket并等待创建进程
          • SystemServer进程启动
          • SystemServer进程总结

1、简述

本文简要记录下学习Android系统启动的一些细节,方便自己记忆和宏观的认识。
分析的源码是8.1.0

2、细节概要

总体流程

启动电源 => 拉起引导程序 => linux内核启动 => init进程启动 => zygote进程 => systemServer进程

Q1: init进程是什么?init进程启动?既然init进程这么重要那么init究竟做了什么呢?
  1. init进程是Android系统中用户空间的第一个进程,进程号是1。
  2. linux内核启动后会在内核空间创建init进程并在用户空间完成初始化。内核空间创建可查阅文后”参考文章1”。这里我们主要重点研究init进程在用户空间做了什么
    1、Android 8.0 系统启动流程之Linux内核启动–kernel_init进程(三)
  3. 功能探究先查看源码后续总结
    如下代码选自内核源码,用户空间的init入口函数,主要做了如上所提到的事情。
//system/core/init/init.cpp
int main(int argc, char** argv) {
    ...
    add_environment("PATH", _PATH_DEFPATH);
    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);

    if (is_first_stage) {
        boot_clock::time_point start_time = boot_clock::now();

        // Clear the umask.
        umask(0);
		// 挂载文件	
        // Get the basic filesystem setup we need put together in the initramdisk
        // on / and then we'll let the rc file figure out the rest.
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        ....
        InitKernelLogging(argv);
        ....
    }
    ...
    // 属性服务初始化 
    property_init();
    ....
    // 启动属性服务
    start_property_service();
    ...
    // 默认为true
    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"));
    ...
    return 0;
}
Q2: 属性服务作用特性

可以理解为记录用户以及软件使用信息的注册表工具,即使系统或软件重启依旧可依据属性服务中的记录进行相应的初始化工作。还可以用于软件间信息的获取等。

属性服务的初始化早于zygote进程,写操作采用socket进程来跨进程通信,读操作采用共享内存来读取。
具体如何初始化启动通信可参考文末的2、3。
2、Android 属性服务研究
3、android 开机启动流程分析(04)init启动中关键服务-属性服务

init进程启动总结
  1. linux 内核阶段进行创建启动,切换到用户空间进行加载
  2. 创建和挂载所需要要的文件
  3. 初始化并启动属性服务
  4. 解析init.rc 脚本文件并创建启动zygote进程
Q3: zygote是什么?zygote进程启动?作用?

zygote进程创建了应用程序进程和SystemServer进程

int main(int argc, char** argv) {
   parser.ParseConfig("/init.rc");
}

init.rc是一个非常重要的配置文件,它是由Android初始化语言编写的脚本,共包含5中类型语句(参考4),如下所示。查看下面代码可以发现,会启动classname为main的service,而我们在特定系统的rc文件中发现init新建了一个名为zygote的进程其classname为main,则就代表启动了zygote。
执行do_class_start最终会fork子进程并启动这个进程,那么zygote进程启动起来了。

//system/core/rootdir/init.rc
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
// ro.zygote变量,它可以被理解为一个环境变量
import /init.${ro.zygote}.rc
// 初始化创建一系列文件
on zygote-start && property:ro.crypto.state=unencrypted
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=unsupported
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on nonencrypted
    class_start main
    class_start late_start
....    

ro.zygote变量,它可以被理解为一个环境变量,这里我们看64里面的。
init进程会创建名为zygote的进程,程序的执行路径为
/system/bin/app_process64,zygote的classname为main

//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

app_process关联到app_main中,由于zygote进程包含有zygote则runtime会进入分之一中,进入具体的start方法这里会解析字符串和args最终会jni调用com/android/internal/os/ZygoteInit 中的main函数

//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){
	...
	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.");
    }
}

我们看看AndroidRumtime具体做了哪些操作

//frameworks/base/core/jni/AndroidRuntime.cpp
/*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */
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);
    }
    
    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 {
           // ****************************
           // 通过JNI调用ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }

}

如上所示AndroidRuntime 首先启动了java虚拟机,然后注册了JNI方法,再然后解析传递的的路径jni调用java层的main方法

好了终于c++层切换到我们的java框架层了。我们深入探索到ZygoteInit.java去看看内部做了哪些操作。

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        final Runnable caller;
        try {
            // Report Zygote start time to tron unless it is a runtime restart
            ...
            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)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }
			//******
			// 1、创建一个Service端的socket,sockerName为zygote
            zygoteServer.registerServerSocket(socketName);

            // 2、第一次加载会预加载类和资源 
            if (!enableLazyPreload) {   
                preload(bootTimingsTraceLog);
                ....
            } 
			
			// 3、fork systemServer
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
                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.
            // 4、等待am请求,早于fork进程
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }
}

Zygote进程启动总结
  1. init进程加载init.rc ,执行do_class_start fork进程并启动了zygote进程,交由AndroidRuntime执行具体流程
  2. zygote内部借助AndroidRuntime创建java虚拟机并为java虚拟机注册JNI方法
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的java框架层
  4. 创建了一个名为zygote的Server端的socket,并通过runSelectLoop方法等待AMS请求来创建新的应用进程
  5. fork并启动了SystemServer进程
创建服务端的socket并等待创建进程

在zygote进程中创建了一个名为 ANDROID_SOCKET_zygote的socket,
用途是在该socket上等待AMS请求zygote进程来创建新的应用程序进程

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
public static void main(String argv[]) {
	...
	zygoteServer.registerServerSocket(socketName);
	...
	caller = zygoteServer.runSelectLoop(abiList);
}
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
class ZygoteServer {
    void registerServerSocket(String socketName) {
        if (mServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                // socket创建并返回
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }
}
	//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);
		//****
		//无限循环等待AMS请求	
        while (true) {
        	...
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
				//服务端与客户端连接了
                if (i == 0) {
                    // *****************
                    // 添加入队列 接收到消息
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    try {
                        ZygoteConnection connection = peers.get(i);
                        // ****************
                        //创建新的应用程序进程
                        final Runnable command = connection.processOneCommand(this);
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at this
                            // stage if processOneCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }
                            return command;
                        } else {
                            // We're in the server - we should never have any commands to run.
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(i);
                                fds.remove(i);
                            }
                        }
                    } catch (Exception e) {
                        if (!mIsForkChild) {
                            ZygoteConnection conn = peers.remove(i);
                            conn.closeSocket();
                            fds.remove(i);
                        } else {
                            Log.e(TAG, "Caught post-fork exception in child process.", e);
                            throw e;
                        }
                    }
                }
            }
        }
    }

具体接收到AMS通知新进程的代码如下所示,接收到通知后会由

//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
class ZygoteConnection {
	    Runnable processOneCommand(ZygoteServer zygoteServer) {
	    ...
        fd = null;
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
        try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                return handleChildProc(parsedArgs, descriptors, childPipeFd);
            } 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);
        }
    }
}
SystemServer进程启动
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
	public static void main(String argv[]) {
		  ....	
	      if (startSystemServer) {
	          Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
	          if (r != null) {
	              r.run();
	              return;
	          }
	      }
	      ....
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    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,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);
            /* Request to fork the system server process */
            // 从zygote进程fork出一个systemServer
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
			// 因为子进程会复刻父进程,所以在SystemService中关闭socket
            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }
}    
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
	    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        if (parsedArgs.invokeWith != null) {
        	...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
            	/*
                 * 1、路径类加载
                 */
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             * 执行zygoteInit方法
             */
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

    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();
        // 启动binder线程池
        ZygoteInit.nativeZygoteInit();
        // 进入SystemServer的main方法
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
}

这里创建线程池就不去深究了
systemServer启动了Binder线程池,那么就可以通过binder线程池进行通信。

下面我们来查看下SystemServer是如何唤醒的

//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
	    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        final Arguments args = new Arguments(argv);
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    private 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);
        }
        return new MethodAndArgsCaller(m, argv);
    }

    static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
            	// ******
                // 最终反射调用 SystemServer的main方法
                // ******
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }
}
//frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
    /**
     * The main entry point from zygote.
     * 从zygote进入的主要入口
     */
	    public static void main(String[] args) {
        new SystemServer().run();
    }

    private void run() {
        try {
        	// 创建消息looper
            Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            // 创建系统的context
            createSystemContext();

            // ***** Create the system service manager.
            // 创建SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            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) {
            throw ex;
        } finally {
            traceEnd();
        }
        // Loop forever.
        // 执行loop循环
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

    /*
    * 创建context
    */
    private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
}

我们以启动UserManagerService来简单了解下SystemServiceManager如何启动一个服务的。

private void startBootstrapServices() {
	...
	traceBeginAndSlog("StartUserManagerService");
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        traceEnd();
}
//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public class SystemServiceManager {
    // Services that should receive lifecycle events.
    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }
}
//frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
public class UserManagerService extends IUserManager.Stub {
	    public static class LifeCycle extends SystemService {

        private UserManagerService mUms;

        /**
         * @param context
         */
        public LifeCycle(Context context) {
            super(context);
        }

        @Override
        public void onStart() {
            mUms = UserManagerService.getInstance();
            /**
	         * 调用了SystemService的publishBinderService方法
	         */
            publishBinderService(Context.USER_SERVICE, mUms);
        }

        @Override
        public void onBootPhase(int phase) {
            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
                mUms.cleanupPartialUsers();
            }
        }
    }
}

下面去探究 SystemService的publishBinderService 调用了哪个方法,可以发现实际上是将service添加到了ServiceManager中

//frameworks/base/services/core/java/com/android/server/SystemService.java
// 所有生命周期方法都是从系统服务器的主循环线程调用的
public abstract class SystemService {
	protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }
    
    final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }
}

我们继续看下ServiceManager的addService方法,那么又通过IServiceManager的实现类进行添加

//frameworks/base/core/java/android/os/ServiceManager.java
public final class ServiceManager {
    private static IServiceManager sServiceManager;
	public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }
    
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }
}

最终添加到了Binder线程池中了,这里对binder线程池不是特别理解,后续需要研究。
service进入binder线程池后也就可以跨进程进行通信了。

public class BinderInternal {
    /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();
}
//frameworks/base/core/java/android/os/ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager{
	    /**
	     * Cast a Binder object into a service manager interface, generating
	     * a proxy if needed.
	     */
	    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ServiceManagerProxy(obj);
    }

    public ServiceManagerNative()
    {
        attachInterface(this, descriptor);
    }

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    public IBinder asBinder() {
        return mRemote;
    }

    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

    public IBinder checkService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }
    
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        // 将service写入了对象池中
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }
  }  
}

此时各种系统服务其实是运行在SystemServer进程中的,那么我们在应用中调用各种系统服务其实就是在进程间通信了。后续我也会去多多研究binder,毕竟大牛博主都说了binder是跨向Android高级的第一步,加油。

SystemServer进程总结
  1. 由zygote进程fork得来
  2. 调用Looper#prepareMainLooper()准备 Android 主线程Looper,调用Looper#loop()让主线程的Looper跑起来
  3. 创建应用上下文
  4. 启动Binder线程池,用于与其他进程通信
  5. 创建SystemServiceManager 并启动各种系统服务

参考文章
1、Android 8.0 系统启动流程之Linux内核启动–kernel_init进程(三)
2、Android 属性服务研究
3、android 开机启动流程分析(04)init启动中关键服务-属性服务
4、安卓初始化语言
Android zygote 进程的启动过程分析
参考书籍
<>

你可能感兴趣的:(经典源码)