Android开机启动流程

一. 启动架构

当前一些智能设备都是由硬件结合体加上操作系统组装而成,由操作系统控制相应的软件去操作硬件。常见的操作系统有Windows,Android,Linux,MacOS。

Android系统启动过程由图从下往上的可以分为5个过程,然后依次分为Boot Loader -> Kernel -> Native -> Framework -> App,如下图:
在这里插入图片描述
这个启动流程也可以简化成两个阶段:

1.BIOS 阶段:

BIOS 在主板的 ROM 中存储, 加电之后便会启动

2.bootloader 阶段, 读取磁盘上的操作系统:

0 号进程:所有进程的祖先, 这是 Linux 唯一一个没有通过 fork 或者 kernel_thread 产生的进程,初始化进程管理、内存管理, 初始化驱动程序 Display, Camera Driver, Binder Driver 等相关工作;

1 号进程(init 进程):为用户进程, 是所有用户态进程的祖先;

2 号进程:为内核进程, 负责内核态所有进程的管理和调度, 是所有 Linux 内核进程的祖先;

进程的分工可以用如下图总结:

在这里插入图片描述
进程主要分用户进程和内核进程,我们主要看用户进程。

二. init进程

从 Init 进程的启动主要的职责如下:

  1. 挂载文件系统, 创建驱动目录和驱动设备文件;

  2. 解析启动脚本(init.rc);

  3. 执行脚本指令;

    a. 启动服务管理进程(ServiceManager);

    b. 启动图像渲染进程(SurfaceFlinger);

    c. 启动 Zygote 进程;

三. 服务管理进程ServiceManager

从名字上就可以看出来它是用来管理系统中的service,通过Binder去协助获取服务(AMS,PKMS);

  1. 打开 Binder 驱动;

  2. 注册为当前进程为 Binder 上下文的管理者;

  3. 将当前线程注册为 Binder Loop 线程;

在Android,Binder也是Android里面的进程通信的主要方式。一般一个app有一个进程,然后n多的线程依附在进程去运行通信。在同一个进程中的线程通信是比较方便(Android提供了Handler),而不同进程之间通信比较困难。举个例子将一个个进程假设成一个个城市,去城市里面某个地方是比较简单,可以通过城市公交,地铁等等。而从一个城市到另一个城市就相对困难点,如需要到特定地方搭大巴,高铁或者飞机。

四. 图像渲染进程SurfaceFlinger
在这里插入图片描述

SurfaceFlinger 进程主要负责 VSYNC 信号的分发和图层的合成。

  1. main 函数初始化 Binder 驱动;

  2. SurfaceFlinger 的创建:

    a. DispSyncThread: 用于将 DispSync 处理好的 SW-VSYNC 分发给监听者 DisplaySyncSource;

    b. EventThread-app: 维护了与 App 进程的 Connection 连接, 用于接收 DispSyncThread 发送的信号, 并且发送给 App 端, 会触发 Choreographer 执行 View 的绘制流程;

    c. EventThread-sf: 维护了与 SurfaceFlinger 的 Connection, 接收到 VSYNC 后, 会调用 cb_eventReceiver 执行图层的合成操作;

    d. EventControlThread: 用于控制硬件 Vsync 的开关;

五. Zygote

Zygote 是在 init 进程启动过程中启动的, 主要负责进程的孵化。包含SystemServer进程和应用进程。

启动之后会调用 app_main.cpp 的 main 函数, 主要有两个方面的初始化:

  1. Native 层调用 AndroidRuntime::start

    a. 启动 ART 虚拟机;

  2. Java 层调用 ZygoteInit 的 main 方法

    a. 预加载资源;

    b. 创建Socket:用于后续监听是否有 fork 请求;

    c. 创建SystemService系统服务进程:启动死循环

    d. 监听Socket端口, 响应进程创建请求;
    在这里插入图片描述

六. SystemServer

SystemServer是由 Zygote 进程孵化的第一个进程, 它的初始化和启动流程如下:

1.创建:通过 Zygote.fork 创建

2.初始化:

a. Native 初始化:

  startThreadPool 启动 Binder 驱动线程池的主线程;

  主线程的 run 方法会执行 joinThreadPool 进入一个 loop 不断的与 Binder 驱动交互;

b. Java 初始化:

 找到SystemServer的main函数
  1. 启动

    a. 引导服务

    启动 ActivityManagerService;

    启动 PackageManagerService;

b. 核心服务;

 启动PowerManagerService等等...

c. 其他服务;

  启动 InputManagerService;

  启动 WindowManagerService;

  回调 AMS 的 systemReady;

  启动 SystemUi 服务进程, 为 App 提供通用的 UI 组件:

     如状态栏 StatusBar, 通知 NotificationChannels, 最近任务列表 Recents…;

  启动 Launcher 进程;

在这里插入图片描述
4. 进入 Looper 死循环, 保证SystemServer进程长久存活;

七. PackageManagerService(PKMS)

Android开机时很久的两个主要原因一个是启动80多种服务(如ActivityManagerService),另一个原因是去获取手机所有app的信息,并重新安装一遍,这个过程是很耗时。

Android 系统中核心服务之一,管理着所有跟 package 相关的工作,常见的比如安装、卸载应用。

  1. PKMS的启动

    a. 解析应用程序备份信息 package.xml/package-backup.xml

     为应用程序分配 UserID;
    

    b. 扫描应用程序安装目录

    PKMS 使用 Package 对象来描述一个已经安装的应用程序, 它会从 base.apk 中解析 AndroidManifest.xml 中四大组件的信息, 将它封装到 Pacakge 中;
    

    c. 发布应用数据

    将安装包内的 Android 四大组件发布到 PMS 的 mActivity, mServices… 集合中。这个过程总的来说就是获取app的信息;
    
  2. PKMS 安装应用:
    Android的安装主要有两种方式:

    a. 通过 Session 发起(adb, 手动点击安装)

    提前将安装包拷贝到 “data/app/vmdl${sessionId}.tmp/” 目录下;
    
    再通过 Session commit, 通知 PKMS 的 PKMS.installStage 进行安装;
    

    b. 通过系统的软件商店自动发起

    直接通过 PKMS 的 PKMS.installStage 进行安装;
    

八. WindowManagerService(WMS)

WindowManagerService即窗口管理服务。顾名思义,主要用于进行窗口的管理,以及对事件进行管理和分发。

wms的整个启动过程涉及3个线程: system_server主线程, “android.display”, “android.ui”。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
九. InputManagerService(IMS)

InputManagerService是Android为了处理各种用户操作而抽象的一个服务。

在这里插入图片描述

  1. IMS的初始化

    a. 创建线程InputReaderThread, 使用InputReader读取输入设备产生事件到QueuedInputListener;

    b. 创建线程InputDispatcherThread, 使用InputDispatcher分发数据;

  2. IMS与应用进程的交互

    a. 当应用进程通知WMS创建了一个窗体时, 会创建InputChannel输入通道组;

    b. 将服务端的新建的WindowState和InputChannel注册到IMS中;

    c. 客户端监听 InputChannel

    应用进程拿到WMS传递过来的InputChannel后便会构建一个InputChannelReceived;

    InputChannelReceived在Native层通过Looper的epoll监听了InputChannel的Socket端口;

    有数据写入便会通过JNI调用dispatchInputEvent分发到Java层;

总的来说,首先有一个线程在不断的监听屏幕,一旦有触摸事件,就将事件捕获并通过WMS的InputChannel知道是哪个Windows的,然后分发指定的Windows处理;
在这里插入图片描述

十. Launcher进程启动

当Android的80多种服务都启动完毕之后, 会回调AMS的systemReady启动第一个应用app,即Launcher这个App,Launcher也叫做桌面应用。

  1. Launcher进程采用Binder IPC向system_server进程发起startActivity请求;

  2. system_server进程接收到请求后,向zygote进程发送创建进程的请求;

  3. Zygote进程fork出新的子进程,即App进程;

  4. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;

  5. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;

  6. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;

  7. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

  8. 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。

app启动的流程图如下:
在这里插入图片描述

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值