【Android学习】Android 启动过程中的1号进程init

系列文章目录

由于工作原因,需要通过一些安卓Demo来学习熟悉部门相关业务,配完环境后,看了下手头的电子书,内容很多,最近正好做一些学习笔记整理。


文章目录

  • 系列文章目录
  • 前言
  • 一、Android基本架构(从为什么要学习Android系统)?
  • 二、Android的启动流程(为什么要学习Android启动过程)?
    • 1. BOOT:
    • 2. BootLoader:
    • 3. Linuxn内核:
    • 4. Zygote:
    • 5. System Server:
    • 6.Aapplication:
  • 三、Android的启动流程(为什么要学习Android启动过程)?


前言


本文首先介绍Android的基本架构,接着介绍整体的启动流程,最后根据init进程所在的位置,展开介绍。

由于工作原因,需要通过一些安卓Demo来学习熟悉部门相关业务,配完环境后,看了下手头的电子书,内容很多,最近正好做一些学习笔记整理,我带大概分了下类:

  • Android 系统——技术原理与核心机制
    《Android技术内幕》、《深入理解Android》、《深入理解Android内核设计思想》
  • Android 应用——四大组件与开发功能
    《第一行代码》(快速了解如何上手一个APP)、《Android+APP开发入门》、《Android基础教程》
  • Android 测试——测试工具与系统日志
    《深入理解Android自动化测试》、《Android Log系统介绍》

Android是个很大的领域,相关书籍、博客、教程非常多,但是作为一个未接触过Android的小白,如此巨量的信息让我头疼不已,为了方便自己学习,同时也能帮助到其他类似的伙伴,我将自己的学习思路整理如下。也许笔记不会特别细致深入,但希望整理的内容能帮忙厘清思路。

一、Android基本架构(从为什么要学习Android系统)?

【Android学习】Android 启动过程中的1号进程init_第1张图片 图1 Android基本架构

图1 是官方给出的Android基本架构,一般可以简单概括为:内核、系统库(把ART也算进去)、系统框架、系统应用四个大类,尽管分层清晰,但在我学习过程中,发现很多机制、服务深究起来,还是会横跨多个层。
从Linux操作系统的角度来看,第2层是内核空间与用户空间的分界线,第1层运行于内核空间,第2、3、4层次运行于用户空间。

  • 应用层:应用是用java语言编写的运行在虚拟机上的程序,比如Email客户端,SMS短消息程序,日历等。
  • 应用框架层:这一层是编写Google发布的核心应用时所使用的API框架,开发人员同样可以使用这些框架来开发自己的应用,这样便简化了程序开发的结构设计,但是必须要遵守其框架的开发原则。
  • 系统运行库(C/C++库以及Android运行库)层:当使用Android应用框架时,Android系统会通过一些C/C++库来支持我们使用的各个组件,使其更好的为我们服务,比如其中的SQLite(关系数据库),Webkit(Web浏览器引擎)。
  • Linux内核层:Android的核心系统服务给予Linux2.6内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型等都依赖于该内核。

通过Android的系统架构,也可以看出在针对应用开发、系统开发、驱动开发时需要了解哪些知识

  • Linux知识:Android是基于Linux内核的,编译Android源码也必须在Linux上,所以必须掌握Linux的基础知识(操作区别、简单指令、进程等)。

  • C/C++知识:Android大部分核心库是C/C++的动态链接库,系统大部分隐藏API都是在这里面的。

  • Java知识:Android是80%的Java package,IDE和语言都是Java,尤其是多线程、I/O流、面向对象思想、http和socket网络等。

  • T-SQL知识(可以只是基础的增删改查和子查询)。
    【Android学习】Android 启动过程中的1号进程init_第2张图片
    图2 Android基本架构对应的工作领域

    个人思考: Android的架构就像是一个总纲和字典,测试人员(感觉开发一样)根据需要随时翻看,虽然没有开发人员聚焦深入,但是广度要求比较高。
    Android 系统框架可参考外网博文:Android 操作系统架构开篇-Gityuan

二、Android的启动流程(为什么要学习Android启动过程)?

如图所示, Android启动中有很多资源需要逐步加载,进而一步一步从底层走向我们熟知的界面。
【Android学习】Android 启动过程中的1号进程init_第3张图片
图3 Android启动基本流程

1. BOOT:

启动ROM代码从预先定义的位置开始执行。

它将引导加载程序加载到RAM中并开始执行。这是为了确定在何处找到引导加载程序的第一阶段。一旦引导媒体序列建立,引导ROM将尝试加载第一阶段的引导加载程序到内部RAM。一旦引导加载程序就位,引导ROM代码将执行跳转并继续在引导加载程序中执行。

2. BootLoader:

类似于BIOS系统,包含两个阶段:1、是检测外部RAM,2、是帮助加载程序。

在第二个阶段Bootloader设置网络、内存等需要运行内核的时候,Bootloader可以为内核提供特定目的的配置参数或输入,这可能包含用于设置文件系统、额外内存、网络支持和其他内容的代码。一旦引导加载程序完成了任何特殊任务,它就会寻找要引导的Linux内核。它将从引导媒体(或其他取决于系统配置的源)加载此文件,并将其放在RAM中。它还将在内存中放置一些引导参数,以便内核在启动时读取。

3. Linuxn内核:

Linux内核在Android上启动的方式与在其他系统上类似。

它将设置系统运行所需的一切。初始化中断控制器,设置内存保护,缓存和调度。一旦内存管理单元和缓存被初始化,系统将能够使用虚拟内存并启动用户空间进程。 内核将在根文件系统中查找init进程(在Android开源树的system/core/init下找到),并将其作为初始用户空间进程启动。

init进程有两个任务
1、挂载挂载目录。参考: 史上最详细linux启动过程讲解—没有之一 ;
2、运行init.rc脚本(安卓命令):Android init.rc文件详解_。

严格讲,Android实际是运行于Linux内核上的一系列服务进程,而这些进程则是通过init逐步开启的。在 linux的init的基础上,通过解析一init.rc脚本,执行 开启android需要的一系列服务。

4. Zygote:

Zygote是第一个虚拟机进程,是一个应用程序,原名为app_process,在启动中被修改Zygote。

单独的虚拟机(VMs)实例会在内存中为单独的应用程序弹出,在Android应用程序应该尽快启动的情况下,如果Android os为每个应用程序启动不同的Dalvik VM实例,那么它会消耗大量的内存和时间。因此直接通过Fork一个原始的虚拟机(Zygote),则可以快速得到多个虚拟机,这也是为什么使用Zygote。如图4所示。
【Android学习】Android 启动过程中的1号进程init_第4张图片
图4 Zygote与其他应用进程的共享内存

Zygote有两个作用: 创建SystremServer; 孵化应用进程。

  • Zygote进程预加载系统资源后,然后通过它孵化出其他的虚拟机进程,进而共享虚拟机内存和框架层资源,这样大幅度提高应用程序的启动和运行速度。

  • Zygote进行fork的时候要是单线程,为了避免造成死锁或者状态不一致等问题

  • Zygote的跨进程通信没有采用Binder机制,而是采用本地socket

  • fork其他进程使用Zygote,而非systermserver,是因为Systemserver包含很多应用服务,应用程序不能继承。

  • Zygote的IPC通信机制采用的是Socket而不是binder。

    具体参考:谈谈对Android中Zygote的理解-(知乎)

5. System Server:

进程名为systerm_server,可以说是Zygote的长子。
  • SystemsSever进程通过fork后,调用zygoteInitNative,与Binder通信建立联系。
  • 调用com.android.server.SystemServer的main函数,启动全系统的各项服务。
    【Android学习】Android 启动过程中的1号进程init_第5张图片

图5 SystemServer的启动(《深入理解Android》第四章Zygote)

6.Aapplication:

一般我们是通过桌面->图标->启动APP,这个过程涉及“三进程,六大类”

首先,一开始看到的桌面,同样是一个Activity进程,是系统启动后,首先Lancher的一个进程,主要用于展现界面以及听用户的输入。显示桌面视图的Activity是com.xxxx(系统版本).home包下的名为Launcher的Activity。

应用启动中,由于Launcher是Activity,那点击桌面的事件可以表达为:呈现Android桌面视图(View)->点击View上某个应用图标->产生点击事件->点击事件被响应->通知Android系统的某个/某些进程->Android系统执行某些操作->启动App。
【Android学习】Android 启动过程中的1号进程init_第6张图片

图6 APP启动流程

启动中的三大进程与六个大类如图6所示
三大进程

  • Launcher进程:整个App启动流程的起点,负责接收用户点击屏幕事件,它其实就是一个Activity,里面实现了点击事件,长按事件,触摸等事件,可以这么理解,把Launcher想象成一个总的Activity,屏幕上各种App的Icon就是这个Activity的button,当点击Icon时,会从Launcher跳转到其他页面。
  • SystemServer进程:这个进程在整个的Android进程中是非常重要的一个,地位和Zygote等同,它是属于Application Framework层的,Android中的所有服务,例如AMS, WindowsManager, PackageManagerService等等都是由这个SystemServer fork出来的。
  • App进程:你要启动的App所运行的进程。

六个大类:

  • ActivityManagerService:(AMS)AMS是Android中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要,它本身也是一个Binder的实现类。
  • Instrumentation:监控应用程序和系统的交互。
  • ActivityThread:应用的入口类,通过调用main方法,开启消息循环队列。ActivityThread所在的线程被称为主线程。
  • ApplicationThread:ApplicationThread提供Binder通讯接口,AMS则通过代理调用此App进程的本地方法。
  • ActivityManagerProxy:AMS服务在当前进程的代理类,负责与AMS通信。Applicati
  • onThreadProxy:ApplicationThread在AMS服务中的代理类,负责与ApplicationThread通信。

具体内容可以参考:Android App启动流程详解_mysimplelove的博客-CSDN博客_android app启动流程

采用博客中的总结(APP启动)

  • 启动的起点发生在Launcher活动中,启动一个app说简单点就是启动一个Activity,那么我们说过所有组件的启动,切换,调度都由AMS来负责的,所以第一步就是Launcher响应了用户的点击事件,然后通知AMS;
  • AMS得到Launcher的通知,就需要响应这个通知,主要就是新建一个Task去准备启动Activity,并且告诉Launcher你可以休息了(Paused);
  • Launcher得到AMS让自己“休息”的消息,那么就直接挂起,并告诉AMS我已经Paused了;
  • AMS知道了Launcher已经挂起之后,就可以放心的为新的Activity准备启动工作了,首先,APP肯定需要一个新的进程去进行运行,所以需要创建一个新进程,这个过程是需要Zygote参与的,AMS通过Socket去和Zygote协商,如果需要创建进程,那么就会fork自身,创建一个线程,新的进程会导入ActivityThread类,这就是每一个应用程序都有一个ActivityThread与之对应的原因;
  • 进程创建好了,通过调用上述的ActivityThread的main方法,这是应用程序的入口,在这里开启消息循环队列,这也是主线程默认绑定Looper的原因;
  • 这时候,App还没有启动完,要永远记住,四大组建的启动都需要AMS去启动,将上述的应用进程信息注册到AMS中,AMS再在堆栈顶部取得要启动的Activity,通过一系列链式调用去完成App启动;

三、Android的启动流程(为什么要学习Android启动过程)?

通过学习Android的整体启动流程,我们可以看到,init最重要的就是创建Zygtoe进程(ServiceManager也很重要与Binder通信机制相关),从而进入Android世界,可以说init是衔接Linux内核与Android的重要节点,是这两个世界的分界线。

【Android学习】Android 启动过程中的1号进程init_第7张图片

图7 Init进程的主要操作

init.rc是一系列操作命令,用于开启一系列重要的服务。服务本质是可执行程序,在命令特定项约束下,被init程序运行或者重启。init中陆续启动ServiceManager,Zygote, SystemServer。

到此为止,虽然没有对init这个1号进程展开非常详细的学习,但目前已经掌握init在整个启动中的位置与意义。
具体每个细节与技术(如:Zygote、Servicemanager、SystemService)在后续分别学习各个模块时展开。
init的源码学习可以参考: Android的init过程详解(一) - 银河使者 - 博客园
【Android学习】Android 启动过程中的1号进程init_第8张图片

图8 RC命令主要操作(《深入理解Android内核设计思想第7章》)

你可能感兴趣的:(Android学习,android,学习)