博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 系统启动流程
阅读量:6226 次
发布时间:2019-06-21

本文共 18327 字,大约阅读时间需要 61 分钟。

Android系统是基于Linux定制的一款开源的而移动端操作系统,由于其开源的特性,各大手机厂商可以针对其源码进行深度定制,对于开发者来说,有如此庞大且优秀的开源os提供参考,尤其是对移动端的开发者来说,阅读Android系统源码可以帮助我们更好地理解其中的各种机制,平时束手无策的问题也可以在源码中寻找答案。当然光8.0的源码就20多个g,像全部读完几乎是不可能的事,我们主要以framework为主线,以系统运行机制为分支,层层阅读,剥开Android系统的神秘面纱。

Android 系统架构

首先来一张google经典的Android系统架构图:可以看到,从上到下主要分为4层:应用层,framework层,系统库和运行时,Linux内核层。

#Android 启动流程 这里再上一张Android系统启动的流程图,可以看到系统从启动开始是按照一个流程:Loader->kernel->framework->Application来进行的。

Loader层:

  • Boot Rom:当手机处于关机状态时,长按开机键开机,会引导芯片开始从固化在Rom里预设的代码开始执行,然后加载引导程序到Ram
  • Boot Loader:启动Android系统之前的引导程序,主要是检查Ram,初始化参数等

Kernel层

Kernel层指的就是Android内核层,这里一般开机刚刚结束进入Android系统,Kernel层的启动流程如下:

  1. 启动swapper进程(pid=0),这是系统初始化过程kernel创建的第一个进程,用于初始化进程管理、内存管理、加载DisplayCameraBinder等驱动相关工作
  2. 启动kthreadd进程,这是Linux系统的内核进程,会创建内核工作线程kworkder、软中断线程ksoftirqdthermal等内核守护进程。kthreadd是所有内核进程的鼻祖。

Native层

这里的native层主要包括由init进程孵化的用户空间的守护进程,bootanim开机动画和hal层等。InitLinux系统的守护进程,是所有用户空间进程的鼻祖。

  • init进程会孵化出ueventdlogdhealthdinstalldadbd、lm这里写代码片kd等用户守护进程;
  • init进程还会启动ServiceManager(Binder服务管家)、bootanim(开机动画)等重要服务。
  • init进程孵化出Zygote进程,Zygote进程是Android系统第一个Java进程(虚拟机进程),Zygote进程是所有Java进程的父进程。

Framework层

framework层有native层和java层共同组成,协调系统平稳有序的工作。framework 层主要包括以下内容:

  • Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlingerCamera Service等服务。
  • Zygote进程,由Init进程通过解析init.rc文件生成,Zygote是Android系统的第一个Java进程,是所有Java进程的父进程。
  • System Server进程,由Zygote进程fork而来,是Zygote进程孵化的第一个子进程,负责启动和管理整个Java Framework,包括AmsPms等。

App层

Zygote进程孵化的第一个App进程是Launcher进程,也就是我们的桌面进程,也就是我们打开手机看到的用户界面。因为在前面的framework 生成了各种守护进程和管理进程,对于Launcher也就有对应的点击、长按、滑动、卸载等监听。Zygote进程也会创建BrowserPhoneEmail等App进程。也就是说所有的App进程都是由Zygote进程fork生成的。而且上层的进程全部由下层的进程进行管理,包括但不限于界面的注册、跳转,消息的传递。

Zygote进程的启动

了解了Android系统从按下开机键到桌面完整运行在用户眼前的整个流程,我们就可以针对系统的各个过程进行分析。由于是移动开发,平时最多打交道的是应用层,也是就上面的App层,跟我们打交道最多的就是framework层,我们主要关注framework层是如何启动并调度各应用进程协调工作的。从ZygoteInitmain方法开始,我们先看framework启动流程的时序图(省略了一些步骤)大体如下:

1.ZygoteInit.main

public static void main(String argv[]) {        ZygoteServer zygoteServer = new ZygoteServer();        // Mark zygote start. This ensures that thread creation will throw        // an error.        ZygoteHooks.startZygoteNoThreadCreation();		...        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());            }			...			// 1.加载首个Zygote进程的时候,加载参数有start-system-server,即startSystemServer=true			            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.");            }			// 2. 注册zygote服务端localserversocket            zygoteServer.registerServerSocket(socketName);	        ...			// 3.在这里开启了SystemServer,也就是Ams,Pms,Wms...等一系列系统服务            if (startSystemServer) {                startSystemServer(abiList, socketName, zygoteServer);            }            Log.i(TAG, "Accepting command socket connections");            			// 4.while(true) 死循环,除非抛出异常系统中断            zygoteServer.runSelectLoop(abiList);            zygoteServer.closeServerSocket();        } catch (Zygote.MethodAndArgsCaller caller) {            caller.run();        } catch (Throwable ex) {            Log.e(TAG, "System zygote died with exception", ex);            zygoteServer.closeServerSocket();            throw ex;        }    }复制代码

ZygoteInit.main()native层传入初始化参数调用,这里不再赘述,这边主要沿Java的framework层来分析系统的调用,结合上图和代码注释可以看到,加载参数有start-system-server,即startSystemServer=true赋值,紧接着下面会调用ZygoteServer.registerServerSocket(),也就是这里和ZygoteServer的通信用到的是LocalSocket,我们知道跨进程调用最常见的调用方式就是LocalSocketaidl,在framework里也有很多这样通信的。接下来就开启了SystemServer,后面是一个runSelectLoop(),这里其实是一个死循环,当抛出异常终止则会调用zygoteServer.closeServerSocket()来关闭socket连接。我们继续跟进startSystemServer看具体是如何开启系统服务的。

2.startSystemServer

/**     * Prepare the arguments and fork for the system server process.     */    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)            throws Zygote.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,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 {	        //传入准备参数,注意上面参数最后的"com.android.server.SystemServer"            parsedArgs = new ZygoteConnection.Arguments(args);            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */            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 */				// pid = 0 说明创建子进程成功,SystemServer此时拥有独立进程,可以独立在自己的进程内操作了        if (pid == 0) {            if (hasSecondZygote(abiList)) {                waitForSecondaryZygote(socketName);            }            zygoteServer.closeServerSocket();            // 处理SystemServer进程            handleSystemServerProcess(parsedArgs);        }        return true;    }复制代码

这个方法不是很长,看注释可以知道,主要是用来准备SystemServer进程的参数和forkSystemServer进程。前面一堆参数不用看,注意我添加中文注释的地方,传入的参数有一个内容为"com.android.server.SystemServer",这是SystemServer类的全限定名,接下来调用Zygote.forkSystemSeerver(),最后当pid=0时,也就是说明子进程创建成功,如果这时候有两个Zygote进程则等待第二个Zygote进程连接,关闭掉第一个Zygote进程和ZygoteServersocket连接。最后调用handleSystemServerProcess()来处理SystemServer进程。这里的Zygote.forkSystemServer()实际上是调用了native层的forkSystemServer()来fork子进程。这里主要跟进handleSystemServerProcess()看看是如何完成新fork的SystemServer进程的剩余工作的。

3.handleSystemServerProcess

/**     * Finish remaining work for the newly forked system server process.     */    private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws Zygote.MethodAndArgsCaller {		...		// 默认为null,走Zygote.init()流程		        if (parsedArgs.invokeWith != null) {            ...        } else {            ClassLoader cl = null;            if (systemServerClasspath != null) {	            // 创建类加载器,并赋予当前线程                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);                Thread.currentThread().setContextClassLoader(cl);            }            /*             * Pass the remaining arguments to SystemServer.             */            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);        }        /* should never reach here */    }复制代码

parsedArgs.invokeWith默认是为null的,也就是走else流程,可以看到先创建了一个类加载器并赋予了当前线程,然后进入了ZygoteInit.zygoteInit()

4.ZygoteInit.zygoteInit()

/**     * The main function called when started through the zygote process. This     * could be unified with main(), if the native code in nativeFinishInit()     * were rationalized with Zygote startup.

* * Current recognized args: *

    *
  • [--] <start class name> <args> *
* * @param targetSdkVersion target SDK version * @param argv arg strings */ 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(); // Zygote初始化 ZygoteInit.nativeZygoteInit(); // 应用初始化 RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }复制代码

这个方法不是很长,主要工作是Zygote的初始化和Runtime的初始化。Zygote 的初始化调用了native方法,里面的大致工作是打开/dev/binder驱动设备,创建一个新的binder线程,调用talkWithDriver()不断地跟驱动交互。 进入RuntimeInit.applicationInit()查看具体应用初始化流程。

5.RuntimeInit.applicationInit

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws Zygote.MethodAndArgsCaller {        // If the application calls System.exit(), terminate the process        // immediately without running any shutdown hooks.  It is not possible to        // shutdown an Android application gracefully.  Among other things, the        // Android runtime shutdown hooks close the Binder driver, which can cause        // leftover running threads to crash before the process actually exits.        nativeSetExitWithoutCleanup(true);        // 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);        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);        final Arguments args;        try {	        // 解析参数            args = new Arguments(argv);        } catch (IllegalArgumentException ex) {            Slog.e(TAG, ex.getMessage());            // let the process exit            return;        }        // The end of of the RuntimeInit event (see #zygoteInit).        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        // Remaining arguments are passed to the start class's static main        invokeStaticMain(args.startClass, args.startArgs, classLoader);    }复制代码

这个方法也不是很长,前面的一些配置略过,主要看解析参数和invokeStaticMain(),顾名思义,这里的目的是通过反射调用静态的main方法,那么调用的是哪个类的main方法,我们看传入的参数是args.startClass,我们追溯参数的传递过程,发现之前提到的一系列args被封装进ZygoteConnection.Arguments类中,这一系列参数原本是

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",        };复制代码

可以看到,唯一的类的全限定名是com.android.server.SystemServer,追述args = new Arguments(argv)的源码也可以找到答案:

Arguments(String args[]) throws IllegalArgumentException {            parseArgs(args);		}        private void parseArgs(String args[])                throws IllegalArgumentException {            int curArg = 0;            for (; curArg < args.length; curArg++) {                String arg = args[curArg];                if (arg.equals("--")) {                    curArg++;                    break;                } else if (!arg.startsWith("--")) {                    break;                }            }            if (curArg == args.length) {                throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");            }			// startClass 为args的最后一个参数            startClass = args[curArg++];            startArgs = new String[args.length - curArg];            System.arraycopy(args, curArg, startArgs, 0, startArgs.length);        }    }复制代码

6.RuntimeInit.invokeStaticMain

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)            throws Zygote.MethodAndArgsCaller {        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. */ throw new Zygote.MethodAndArgsCaller(m, argv); }复制代码

可以看到,这边走的就是正常的一个反射流程,会对main方法的参数、修饰符等校验,有问题抛出RuntimeException运行时异常,没问题就抛出一个Zygote.MethodAndArgsCaller,这一步的处理可以说是非常奇怪了,既然执行完毕为什么不直接invoke而是抛出异常呢,我们可以看到英文注释的大概解释,这个异常抛出在ZygoteInit.main()方法,执行了异常的run方法,其目的是清除设置中的所有堆栈帧,既然如此我们回到ZygoteInit.main()方法,果然:

try{		...	}catch (Zygote.MethodAndArgsCaller caller) {        caller.run();    }复制代码

抛出该异常调用了caller.run()方法,那我们看这里做了什么:

public static class MethodAndArgsCaller extends Exception            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 {                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);            }        }    }复制代码

可以看到,这里调用了mMethod.invoke(null, new Object[] { mArgs }),也就是执行了SystemServermain方法。

7.SystemServer.main

public static void main(String[] args) {        new SystemServer().run();    }复制代码
try {			...			//主线程在当前进程			Looper.prepareMainLooper();			...            // 初始化系统上下文            createSystemContext();                        // 1.创建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();		}		...        try {            traceBeginAndSlog("StartServices");			//2.开启一些重要的系统服务            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");复制代码

可以看到,这边主要的工作,创建主线程Looper循环器,初始化系统上下文,最关键的还是后面的开启一系列的服务,这些服务就包括了系统服务,跟进sartBootstrapService()看看是如何初始化系统服务的。

8.SystemServer.startBootstrapServices

...		SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);		// 阻塞等待与installd建立socket通道		Installer installer = mSystemServiceManager.startService(Installer.class);		// 1. 在这里开启了Ams        mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);        mActivityManagerService.setInstaller(installer);        ...		// 2.在这里开启了PowerManagerService        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);				// 3.Ams 初始化PowerManager        mActivityManagerService.initPowerManagement();                // Bring up recovery system in case a rescue party needs a reboot        if (!SystemProperties.getBoolean("config.disable_noncore", false)) {            traceBeginAndSlog("StartRecoverySystemService");            //             mSystemServiceManager.startService(RecoverySystemService.class);            traceEnd();        }				mSystemServiceManager.startService(LightsService.class);				mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);				mPackageManagerService = PackageManagerService.main(mSystemContext, installer,                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);        mFirstBoot = mPackageManagerService.isFirstBoot();        mPackageManager = mSystemContext.getPackageManager();        		mSystemServiceManager.startService(UserManagerService.LifeCycle.class);				mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));		复制代码

可以看见启动了很多的系统服务,其中很多的服务目前也不是很了解,主要的是ActivityMangerServicePackageManagerService等主要管理系统的一些服务。自此,Android系统的SystemServer已经启动,并且其相关的各种系统服务已经启动,Ams等重要系统服务也均已开启。Ams是贯穿Android系统的核心服务,负责系统四大组件的启动、切换及其生命周期管理和调度等工作,各个应用程序App作为独立进程需要通过BinderAms进行通信,而AmsSystemServer中通过LocalSocketZygote进行通信。不管是对于系统运行的原理,还是各组件的调度过程,理解Ams的工作原理十分重要,接下来将以此为主线,分别分析Ams、四大组件等的启动流程和生命周期的管理等。

参考资料

Android 8.0.1源码

转载于:https://juejin.im/post/5b7e72bbe51d453894001ef0

你可能感兴趣的文章
jQuery之Deferred对象详解
查看>>
Windows 设置时间同步
查看>>
VS2010 调试C++项目 fatal error LNK1123 错误解决办法
查看>>
EBS OAF 开发中的OAMessageRadioGroup控件
查看>>
调整linux的时钟
查看>>
ObjectOutputStream和ObjectInputStream
查看>>
博客增加二维码功能
查看>>
static作用
查看>>
TCP协议中的三次握手和四次挥手(图解)
查看>>
RDIFramework.NET V2.9版本 WinFom部分新增与修正的功能
查看>>
使用Xcode和Instruments调试解决iOS内存泄漏
查看>>
[翻译] MotionBlur
查看>>
在这些形式的验证码
查看>>
Android学习笔记(四十):Preference使用
查看>>
Codeforces Beta Round #6 (Div. 2 Only) E. Exposition multiset
查看>>
ThinkPhp学习09
查看>>
家庭常用5号/7号电池购买及使用攻略
查看>>
IT架构之IT架构标准——思维导图
查看>>
ZOJ3827 ACM-ICPC 2014 亚洲区域赛的比赛现场牡丹江I称号 Information Entropy 水的问题...
查看>>
List、Map和Set实现类
查看>>