以前知道AMS、PMS这些概念及其功能,开发的过程中也会用到,就是不知道其来源,好奇心害死猫,扒着扒着扒到系统开机启动这个知识层面上来了,好吧,那今天就说说这个吧!

系统开机启动过程

Android系统的启动,主要是指Android手机关机后,长按电源键后,Android手机开机的过程。从系统角度看,Android的启动程序可分为:

  1. bootloader引导
  2. 装载与启动Linux内核
  3. 启动Android系统

其中启动Android系统过程又有以下过程:

  1. 启动Init进程
  2. 启动Zygote
  3. 启动SystemServer
  4. 启动Launcher

android启动过程图示:

zygote

我们知道,Android系统是基于Linux内的。而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。

系统启动的时候执行系统启动脚本system/core/rootdir/init.rc文件,进而触发app_process程序(system/bin/app_process,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main)创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。

Zygote进程最大意义是作为一个Socket的Server端,接收着四面八方的进程创建请求。Android中所有的应用进程的创建都是通过Binder机制请求SystemServer进程,SystemServer进程发送socket消息给Zygote进程,统一由Zygote进程创建出来的。

SystemServer

SystemServer也是一个进程,而且是由zygote进程fork出来的。SystemServer主要用于开启系统重要的一些相关服务,例如:ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)等等,是不是都很熟悉呢?所以SystemServer和Zygote重要级别可以说是平分秋色了。

什么时候开启SystemServer

在zygote开启的时候,会调用ZygoteInit.main()进行初始化:

public static void main(String argv[]) {...ignore some code...//在加载首个zygote的时候,会传入初始化参数,一旦捕获到参数是“start-system-server”,即可开启fork SystemServer指令boolean startSystemServer = false;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {startSystemServer = 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]);}}...ignore some code...//开始fork我们的SystemServer进程if (startSystemServer) {startSystemServer(abiList, socketName);}...ignore some code...}

接下来看一下startSystemServer具体做了什么

/*** Prepare the arguments and fork for the system server process.*/
private static boolean startSystemServer(String abiList, String socketName)throws MethodAndArgsCaller, RuntimeException {...ignore some code...//上面ZygoteInit.main(String argv[])里面的argv就是通过这种方式传递进来的/* 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,1032,3001,3002,3003,3006,3007","--capabilities=" + capabilities + "," + capabilities,"--runtime-init","--nice-name=system_server","com.android.server.SystemServer",};int pid;try {parsedArgs = new ZygoteConnection.Arguments(args);ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);//fork SystemServer/* 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 */if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}handleSystemServerProcess(parsedArgs);}return true;
}

这个方法主要是为了开启SystemServer,这里做了三件事:

  1. 准备fork SystemServer相关参数,例如SystemServer进程的进程Id和组Id均为为1000,进程名称为system_server等。
  2. fork SystemServer,如果返回pid为0则创建成功,否者返回-1或者错误;
  3. 调用handleSystemServerProcess()完成SystemServer进程的初始化工作;

SystemServer进程初始化

上边也说了SystemServer主要用于开启系统重要的一些相关服务,例如:ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)等等,我们看一下代码具体的内部走法:

public final class SystemServer {//zygote的主入口public static void main(String[] args) {new SystemServer().run();}public SystemServer() {// Check for factory test mode.mFactoryTestMode = FactoryTest.getMode();}private void run() {...ignore some code...//创建主线程looper 在当前线程运行android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);android.os.Process.setCanSelfBackground(false);Looper.prepareMainLooper();//加载本地系统服务库,并进行初始化 System.loadLibrary("android_servers");nativeInit();// 创建系统上下文createSystemContext();//初始化SystemServiceManager对象,下面的系统服务开启都需要调用SystemServiceManager.startService(Class<T>),这个方法通过反射来启动对应的服务mSystemServiceManager = new SystemServiceManager(mSystemContext);//开启服务try {startBootstrapServices();startCoreServices();startOtherServices();} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;}...ignore some code...}//初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。private void createSystemContext() {ActivityThread activityThread = ActivityThread.systemMain();mSystemContext = activityThread.getSystemContext();mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);}//在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。private void startBootstrapServices() {...ignore some code...//初始化ActivityManagerServicemActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);//初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);// 现在电源管理已经开启,ActivityManagerService负责电源管理功能mActivityManagerService.initPowerManagement();// 初始化DisplayManagerServicemDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);//初始化PackageManagerServicemPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//开启消息循环Looper.loop();...ignore some code...}
}

SystemServer初始化过程中主要做了以下几个重大工作:

  1. 加载本地系统服务库,系统底层初始化。
  2. 创建消息循环体Looper,这个就是为什么我们在主线程里面不用写Looper,就可以处理UI视图,原来系统已经为我们做了这件事。
  3. 创建系统级上下文,在这个过程中创建我们的主线程ActivityThread,获取系统上下文对象mSystemContext,并设置系统默认主题。
  4. 创建SystemServiceManager对象,开启系统服务三连——引导服务、核心服务以及其他服务。

系统级上下文和我们常用的Context是有区别的,主要是用于服务端(系统级主题和其他服务相关的引导),Context到底是个什么玩意?我在前边的一篇文章中也有总结,这里在阐述一遍,Context英文原意是上下文的意思,在平时开发中涉及到的四大组件及资源操作基本上都离不开Context对象。

服务三连开发者我们最关心的就是引导服务,因为这里面开启的都是我们在日常开发中最容易用到的几个服务:

  1. ActivityManagerService AMS在Android系统中扮演很重要的角色,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似。
  2. PowerManagerService PowerManagerService主要服务Android系统电源管理工作,这样讲比较笼统,就具体细节上大致可以认为PowerManagerService集中处理用户活动(如点击屏幕,按电源键等)、电量变化、用户设置(如在Setting中设置省电模式,飞行模式)、插拔充电器(无线冲,有线冲)等。当发生以上事件时,PowerManagerService都要进行各种状态的更新。
  3. DisplayManagerService DisplayManagerService用来管理显示的生命周期,它决定如何根据当前连接的物理显示设备控制其逻辑显示,并且在状态更改时,向系统和应用程序发送通知等等。
  4. PackageManagerService PackageManagerService(简称PMS),是Android系统中核心服务之一,管理着所有跟package相关的工作,常见的比如安装、卸载应用。
  5. UserManagerService UserManagerService的主要功能是创建和删除用户,以及查询用户信息。Android可以支持多个用户使用系统,通常第一个在系统中注册的用户将默认成为系统管理员。不同用户的设置各不相同,并且不同用户安装的应用及应用数据也不相同。

Launcher

Launcher即桌面,是Android智能设备的窗口,用户使用最频繁的软件之一。Launhcer是Android所有应用的入口,也提供窗口小部件等功能。

Launcher本身就是一个APP,一个提供桌面的APP,Laucher有很多和普通APP不同的地方:

  • Launcher是顶部APP,即任何应用返回后都是到Launcher,不能再继续返回;
  • Launcher是所有应用的入口,可以管理应用;
  • Launcher是Android系统启动后就要显示给用户的应用。

Launcher是由ActivityManagerService启动的,在SystemServer.java的startOtherServices()方法里面的调用 mActivityManagerService.systemReady()进行Launcher的启动之旅,在systemReady方法执行过程中调了用startHomeActivityLocked方法,方法内部通过getHomeIntent拿到Launcher对应的Intent,最后调用startHomeActivity来启动Launcher。

    boolean startHomeActivityLocked(int userId, String reason) {if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL&& mTopAction == null) {// We are running in factory test mode, but unable to find// the factory test app, so just sit around displaying the// error message and don't try to start anything.return false;}Intent intent = getHomeIntent();ActivityInfo aInfo =resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);if (aInfo != null) {intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));// Don't do this if the home app is currently being// instrumented.aInfo = new ActivityInfo(aInfo);aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid, true);if (app == null || app.instrumentationClass == null) {intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);mStackSupervisor.startHomeActivity(intent, aInfo, reason);}}return true;}

ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动,Launcher在启动的时候会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就可以使用这些应用程序了。另外程序安装的时候SystemServer组件会通过PackageManagerServic来安装应用程序,应用程序安装好了以后会以通知的形式通知launcher展示应用图标,卸载同理。

总结

本篇简单分析了一下系统从开机启动到桌面展示这个过程,这里简单总结一下:

  1. 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。
  2. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务(服务三连),例如ActivityThread、AMS、PMS等。
  3. Android中所有的应用进程的创建都是通过Binder机制请求SystemServer进程,SystemServer进程发送socket消息给Zygote进程,统一由Zygote进程创建出来的。
  4. AMS启动Launcher程序,Launcher展示系统相关应用快捷方式。

开机启动我们重在了解过程,明确知道系统几个重要的服务,了解过程中虽然很枯燥但是对开发很有帮助,例如以后的插件化学习,下篇我会着重分析一下Launcher的构造以及Activity的启动过程,加油,期待。

最后

我是i猩人,总结不易,转载注明出处,喜欢本篇文章的童鞋欢迎点赞、关注哦。

参考:

  • https://blog.csdn.net/luoshengyang/article/details/6768304
  • https://www.jianshu.com/p/327f583f970b
  • https://www.jianshu.com/p/6037f6fda285

Android开机启动的那些事相关推荐

  1. Android开机启动流程

    Android开机启动流程 一.APPS PBL(Application primary boot loader:主引导加载程序) 二.XBL(Extensible boot loader:可扩展引导 ...

  2. Android开机启动Activity或者Service方法

    这段时间在做Android的基础开发,现在有一需求是开机启动,按照网上某些博文教程做了下,始终不成功,一开机总是提示所启动的应用程序意外终止,于是参考了Android SDK doc,终于解决问题,下 ...

  3. Android开机启动流程简析

    Android开机启动流程简析 (一) 文章目录 Android开机启动流程简析 (一) 前言 一.开机启动的流程概述 二.Android的启动过程分析 (1).总体流程 init简述 Zygote简 ...

  4. android开机启动service

    为什么80%的码农都做不了架构师?>>>    1.开机启动后系统会发射出一个Standard Broadcast Action,名字叫android.intent.action.B ...

  5. android 开机启动服务。

    今天我们主要来探讨android怎么让一个service开机自动启动功能的实现.Android手机在启动的过程中会触发一个Standard Broadcast Action,名字叫android.in ...

  6. Android 开机启动

    创建一个Receiver,用来监听开机完毕: public class MyReceiver extends BroadcastReceiver {static final String action ...

  7. Android8.0 开机启动脚本,Android开机启动shell脚本(Android 8.0测试OK)

    Android 下做开机启动shell脚本的大致流程如下: 目录 写shell脚本 为脚本写te文件 在init.rc中启动脚本 添加Selinux权限 写shell脚本 比如新建一个init.tes ...

  8. Android开机启动检测和连接wifi检测

    Android启动时,会发出一个系统广播 ACTION_BOOT_COMPLETED,它的字符串常量表示为 "android.intent.action.BOOT_COMPLETED&quo ...

  9. Android开机启动性能优化

    Android 开机启动速度优化 一 在开机启动中,可以借助bootchart 工具分析android的启动过程.bootchart是一个用于linux启动过程性能分析的开源软件工具,在系统启动过程自 ...

最新文章

  1. 构建插件式的应用程序框架(八)----视图服务的简单实现(ZT)
  2. php删除空标签_PHP如何去除Html所有标签、空格以及空白
  3. windows下面的文件拷贝到linux下面出现乱码
  4. 为什么这个SQL Server DBA学习PowerShell--SQL任务
  5. matlab三角函数化简命令,matlab - Matlab - 类似产品的三角函数简化 - 堆栈内存溢出...
  6. Eclipse不编译java文件的解决方法
  7. mysql新增加密字段_mysql字段加密
  8. Python入门(六) list
  9. win10 同步 android,Win10“你的手机应用更新:支持安卓屏幕镜像和通知同步
  10. 内存的读写速度是硬盘的多少倍
  11. Feb14 小白《Linux就该这么学》学习笔记1
  12. TPM设备管理系统对企业生产有何作用?
  13. 微信绑定会员卡服务器出错,微信会员卡跳转到微信小程序出现如下错误?
  14. 计算机网络的雏形为,计算机网络的发展雏形是什么(图文)
  15. LaTeX 多图 排列
  16. 怎样在小方框上打对号 小方框内打对勾 word 方框打对勾
  17. intel固态硬盘误删文件该如何进行恢复
  18. CVE-2014-6321 schannel堆溢出漏洞分析
  19. 逍遥模拟器拷贝android根目录文件,逍遥安卓模拟器怎样将已安装的镜像文件转移到别的磁盘上...
  20. 基于RedHatEnterpriseLinux V7(RHEL7)下SPEC CPU 2006环境搭建以及测试流程(之一)——介绍、安装准备、安装、config文件以及运行脚本介绍

热门文章

  1. Docker 安装 Portainer
  2. 对求解最大公约数算法的一些思考
  3. python两种方法实现线性规划
  4. 金仓数据库KingbaseES高可用概述(高可用架构与最大高可用性的特性)
  5. 数据库索引最左匹配原则
  6. C1认证学习十八、十九(表单元素、转义字符)
  7. 大数据工程师在阿里面试流程是什么?
  8. I Squared Capital将与Rubis就欧洲领先的石油产品、化学品、农产品和化肥存储公司Rubis Terminal开展合作
  9. EtherCAT小体积直流伺服驱控器ELMO智能直流伺服驱动器COPLEY驱动器
  10. 骑马钉 双联 竖版 正反印