转自:http://gityuan.com/android/

一、简述

Android系统非常庞大、错中复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统调用(Syscall)连通系统的内核空间与用户空间。用户空间主要采用C++和Java代码,通过JNI技术打通用户空间的Java层和Native层(C++/C),从而融为一体。

Google官方提供了一张经典的四层架构图,从下往上依次分为Linux内核、系统库和Android运行时环境、框架层以及应用层这4层架构,其中每一层都包含大量的子模块或子系统。这只是如垒砖般地分层,并没有表达Android整个系统的内部架构、运行机理,以及各个模块之间是如何衔接与配合工作的。为了更深入地掌握Android整个架构思想以及各个模块在Android系统所处的地位与价值,计划以Android系统启动过程为主线,以进程的视角来诠释Android M系统全貌,全方位的深度剖析各个模块功能,争取各个击破。这样才能犹如庖丁解牛,解决、分析问题则能游刃有余。

二、Android架构

Google提供的4层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌,阐述Android内部的环环相扣的内在联系。

系统启动架构图

点击查看大图

图解: Android系统启动过程由上图从下往上的一个过程:Loader -> Kernel -> Native ->Framework -> App,接来下简要说说每个过程:

2.1 Loader层

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

2.2 Kernel层

Kernel层是指Android内核层,到这里才刚刚开始进入Android系统。

  • 启动Kernel的0号进程:初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
  • 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖

2.3 Native层

这里的Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖

  • init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;
  • init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
  • init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程,Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

2.4 Framework层

  • Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:

    • 加载ZygoteInit类,注册Zygote Socket服务端套接字;
    • 加载虚拟机;
    • preloadClasses;
    • preloadResouces。
  • System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。
  • Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service,等服务。

2.5 App层

  • Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;
  • Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
  • 所有的App进程都是由Zygote进程fork生成的。

2.6 Syscall && JNI

另外,对于Android整个系统架构,关于学习和研究Android的经验之谈,可以查看 如何自学Android

三、通信方式

无论是Android系统,还是各种Linux衍生系统,各个组件、模块往往运行在各种不同的进程和线程内,这里就必然涉及进程/线程之间的通信。对于IPC(Inter-Process Communication, 进程间通信),Linux现有管道、消息队列、共享内存、套接字、信号量、信号这些IPC机制,Android额外还有Binder IPC机制,Android OS中的Zygote进程的IPC采用的是Socket机制,在上层system server、media server以及上层App之间更多的是采用Binder IPC方式来完成跨进程间的通信。对于Android上层架构中,还多时候是在同一个进程的线程之间需要相互通信,例如同一个进程的主线程与工作线程之间的通信,往往采用的Handler消息机制。

想深入理解Android内核层架构,必须先深入理解Linux现有的IPC机制;对于Android上层架构,则最常用的通信方式是Binder、Socket、Handler,当然也有少量其他的IPC方式,比如杀进程Process.killProcess()采用的是signal方式。下面说说Binder、Socket、Handler:

3.1 Binder

Binder作为Android系统提供的一种IPC机制,无论从系统开发还是应用开发,都是Android系统中最重要的组成,也是最难理解的一块知识点,想了解为什么Android要采用Binder作为IPC机制? 可查看我在知乎上的回答。深入了解Binder机制,最好的方法便是阅读源码,借用Linux鼻祖Linus Torvalds曾说过的一句话:Read The Fucking Source Code。下面简要说说Binder IPC原理。

Binder IPC原理

Binder通信采用c/s架构,从组件视角来说,包含Client、Server、ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务。

  • 想进一步了解Binder,可查看Binder系列—开篇,Binder系列花费了13篇文章的篇幅,从源码角度出发来,讲述驱动、native、framework、app四个层面的整个完整流程。根据有些读者反馈这个系列还是不好理解,这个binder涉及的层次跨度比较大,后续review的时候,计划再从通信的角度写一篇通俗易懂的binder文章,从上之下来串起一遍。

3.2 Socket

Socket通信方式也是C/S架构,比Binder简单很多。在Android系统中采用Socket通信方式的主要:

  • zygote:用于孵化进程,系统进程system_server孵化进程时便通过socket向zygote进程发起请求;
  • installd:用于安装App的守护进程,上层PackageManagerService很多实现最终都是交给它来完成;
  • lmkd:lowmemorykiller的守护进程,Java层的LowMemoryKiller最终都是由lmkd来完成;
  • adbd:这个也不用说,用于服务adb;
  • logcatd:这个不用说,用于服务logcat;
  • vold:即volume Daemon,是存储类的守护进程,用于负责如USB、Sdcard等存储设备的事件处理。

等等还有很多,这里不一一列举,Socket方式更多的用于Android framework层与native层之间的通信。Socket通信方式相对于binder非常简单,所以一直没有写相关文章,为了成一个体系,下次再补上。

3.3 Handler

Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间通信,Handler消息机制是由一组MessageQueue、Message、Looper、Handler共同组成的,为了方便且称之为Handler消息机制。

有人可能会疑惑,为何Binder/Socket用于进程间通信,能否用于线程间通信呢?答案是肯定,对于两个具有独立地址空间的进程通信都可以,当然也能用于共享内存空间的两个线程间通信,这就好比杀鸡用牛刀。接着可能还有人会疑惑,那handler消息机制能否用于进程间通信?答案是不能,Handler只能用于共享内存地址空间的两个线程间通信,即同进程的两个线程间通信。很多时候,Handler是工作线程向UI主线程发送消息,即App应用中只有主线程能更新UI,其他工作线程往往是完成相应工作后,通过Handler告知主线程需要做出相应地UI更新操作,Handler分发相应的消息给UI主线程去完成,如下图:

由于工作线程与主线程共享地址空间,即Handler实例对象mHandler位于线程间共享的内存堆上,工作线程与主线程都能直接使用该对象,只需要注意多线程的同步问题。工作线程通过mHandler向其成员变量MessageQueue中添加新Message,主线程一直处于loop()方法内,当收到新的Message时按照一定规则分发给相应的handleMessage()方法来处理。所以说,而Handler消息机制用于同进程的线程间通信的核心是线程间共享内存空间,而不同进程拥有不同的地址空间,也就不能用handler来实现进程间通信。

上图只是Handler消息机制的一种处理流程,是不是只能工作线程向UI主线程发消息呢,其实不然,可以是UI线程想工作线程发送消息,也可以是多个工作线程之间通过handler发送消息。更多关于Handler消息机制文章:

要理解framework层源码,掌握这3种基本的进程/线程间通信方式是非常有必要,当然Linux还有不少其他的IPC机制,比如共享内存、信号、信号量,在源码中也有体现,如果想全面彻底地掌握Android系统,还是需要对每一种IPCd机制都有所了解。

Android开篇(转)的更多相关文章

  1. Android系统全貌 (转)

    转自Gityuan的Android开篇,对自我学习作进一步整理. Android系统以Linux内核作为基底,上层采用Native层和Java层.系统分为内核空间和用户空间,并通过系统调用(Sysca ...

  2. 如何自学Android

    看到很多人提问非科班该如何学习编程,其实科班也基本靠自学.有句话叫"师傅领进门修行靠个人",再厉害的老师能教你的东西都是很有限的,真正的修行还是要靠自己.博主本科是数学专业,虽研究 ...

  3. Android核心机制

    Android开篇 图解Android - Zygote, System Server 启动分析 图解Android - Binder 和 Service 图解Android - System Ser ...

  4. 转自:如何自学Android(强烈推荐)

    转自: http://gityuan.com/2016/04/24/how-to-study-android/ 看到很多人提问非科班该如何学习编程,其实科班也基本靠自学.有句话叫“师傅领进门修行靠个人 ...

  5. 当我们按下电源键,Android 究竟做了些什么?

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由goo发表于云+社区专栏 相信我们对Android系统都不陌生,而Android系统博大精深,被各种各样的智能设备承载的同时,我们会否 ...

  6. 【重走Android之路】【开篇】序

    [重走Android之路][开篇]   [序]         本人Nodin,偶尔也叫MoNodin,朋友们都喜欢叫我丁,还有个笔名叫陌上幽人,文艺时叫恋风,发奋时叫不肯腐烂的土壤...也许你觉得我 ...

  7. Android 字体修改,所有的细节都在这里 | 开篇

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章. 未经允许,不得转载. 序 在 Android 下使 ...

  8. 【转】Android系统开篇

    版权声明:本站所有博文内容均为原创,转载请务必注明作者与原文链接,且不得篡改原文内容.另外,未经授权文章不得用于任何商业目的. 一.引言 Android系统非常庞大.错综复杂,其底层是采用Linux作 ...

  9. 【Android Studio探索之路系列】之中的一个:Android Studio开篇

    作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.co ...

随机推荐

  1. 使用AS3输出ByteArray为16进制

    package { import flash.utils.ByteArray; /** * 输出ByteArray为16进制 * @author Rise */ public class Byte2H ...

  2. WebMatrix之WebMatrix.Data

    WebMatrix之WebMatrix.Data WebMatrix数据访问系列目次: WebMatrix之数据访问 WebMatrix之WebMatrix.Data WebMatrix之WebMat ...

  3. 写在复习MVC后

    MVC的一些 今天把MVC复习了下,包括官方文档以及各种中文博客. 官方文档里面最能说明的问题的图片,相对于传统的MVC,苹果分离了View和Model之间的通信,实现了更好的复用性.我觉得MVC更 ...

  4. 使用Source Safe for SQL Server解决数据库版本管理问题(转载)

    简介 在软件开发过程中,版本控制是一个广为人知的概念.因为一个项目可能会需要不同角色人员的参与,通过使用版本控制软件,可以使得项目中不同角色的人并行参与到项目当中.源代码控制使得代码可以存在多个版本, ...

  5. java web 开发 购物车功能的实现

    为了方便自己以后复习,所以写的比较仔细,记录下自己的成长..... 既然是做购物车,那么前提条件是首先需要一系列商品,也就是要建一个实体,这里建了一个商品表. 通过查询在浏览器上显示 基本显示已经做好 ...

  6. spring服务定位器类

    此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:通过持有的Spring应用场景ApplicationContext,可在任何地方获取bean. 1. 服务定位器类:S ...

  7. Redisd VS Memcached

    Redis也常常被当作 Memcached的挑战者被提到桌面上来.关于Redis与Memcached的比较更是比比皆是.然而,Redis真的在功能.性能以及内存使用效率上都超越了Memcached吗? ...

  8. 【转载】Android Metro风格的Launcher开发系列第二篇

    前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客Android Metro风格的Launcher开发系列第一篇写了如 ...

  9. margin-top无效的解决方法

    先上代码: <div id="content" style=" width:750px; height:300px; background:#C29A29; mar ...

  10. checkbox勾选判断

    var xieYi=document.getElementById("xieYi"); if(!xieYi.checked){ alert("请先阅读并勾选购买协议!&q ...