目录

Android系统架构ABC

1)      Android的历史

2)      Android 系统框架一览

a)应用程序层

b) 应用程序框架层

c)系统库和Android运行时

Dalvik模式的缺点

ART模式(Android Runtime)的优点

d) Linux内核

Android 开源框架

Android 标准库

3)      通信基石 – Binder模式

IPC机制种类

Binder通信机制简介

为啥新发明一个Binider通信机制

Binder通信模型

Binder通信机制原理图

J2EEAndroid两种RPC的比较:

4)      消息队列(MessageQueue, Looper, Handler)

5)      Framework启动过程: zygote进程和system进程

6)      包管理服务PackageManagerService

7)      第一个应用程序进程的启动过程

8)      AMS活动管理, WMS窗口管理, View系统的工作原理

android内核三大核心成员介绍

整个Android态系统工作原理概述

9)      总结

 

1)    Android的历史

了解一个事物,往往要从其出身开始,这样才能完整地明白它到底是什么东西。Android的历史渊源要追溯到90年代初,Andriod之父 Andy Rubin还在苹果子公司开发第一代手机OS “MagicCap”开始。

 

我用一段话简短概述iPhoneAndroid,苹果和谷歌之间的争端的历史缘由:

 

IOS产生的历史:

Steve Jobs 1976年创建了苹果公司, 后于1985年离开苹果,创立了NeXTComputer”这家公司,创建了一款用Object-C语言编写的叫“NeXTSTEP”的OS,之后在”NeXTSTEP”基础上创造了“Mac OSX”系统,这就是iPhone OS 的基础,简称IOS。后来1996年底,苹果公司又收购NeXT公司,这样Jobs又回到了苹果公司。

 

Android产生的历史:

1990年,苹果公司的手持设备部门独立,特地成立了”GeneralMagic” 的子公司,研究手机操作系统。Android之父89年刚进苹果公司的26岁的年轻人——Andy Rubin,认定手机OS发展前景良好,也加入了这个部门, 参与了”MagicCap” OS的开发,后于95年离开了苹果公司。2003年,Andy Rubin创建了Android公司,仅仅22个月之后,2005年被谷歌收购!然后,谷歌Android部门立马投入展开了短信、手机检索等业务,同时基于Linux的通用平台也进入了开发。经过2年的研究,2007115日, Android第一代系统 1.0 beta发布,不过只作为一个面向开发者的软件开发包(SDK)进行发布。之后经过1年的不断优化,2008923,发布Android操作系统中的第一个正式版本:Android 1.0,代号为铁臂阿童木(Astro)仅仅1年之后,便开始了Android打败诺基亚的Symbian,与IPhone两分天下的辉煌时代!

 

总而言之,无论Android 还是 iPhone, 都是苹果的员工辞职之后,搞出来的。这就是AndroidiPhone与苹果公司的渊源!!!这也是苹果一直将安卓列为侵权产品的缘由。苹果方面表示,Android系统创始人Andy Rubin有关Android系统的理念之一诞生于他供职苹果期间。

 

具体iPhoneAndroid产生的历史渊源可以查看链接:

http://tech.163.com/14/0426/11/9QOMTFMT00094ODU.html

 

具体Android各个历史版本可以查看链接:

http://zh.wikipedia.org/zh-cn/Android%E6%AD%B7%E5%8F%B2%E7%89%88%E6%9C%AC


2)    Android 系统框架一览

 


a)应用程序层

      该层提供一些核心应用程序包,例如电子邮件、短信、日历、地图、浏览器和联系人管理等。同时,开发者可以利用Java语言设计和编写属于自己的应用程序,而这些程序与那些核心应用程序彼此平等、友好共处。

b) 应用程序框架层

    该层是Android应用开发的基础,开发人员大部分情况是在和她打交道。应用程序框架层包括活动管理器、窗口管理器、内容提供者、视图系统、包管理器、电话管理器、资源管理器、位置管理器、通知管理器和XMPP服务十个部分。在Android平台上,开发人员可以完全访问核心应用程序所使用的API框架。并且,任何一个应用程序都可以发布自身的功能模块,而其他应用程序则可以使用这些已发布的功能模块。基于这样的重用机制,用户就可以方便地替换平台本身的各种应用程序组件。

c)系统库和Android运行时

    系统库包括九个子系统,分别是图层管理、媒体库、SQLiteOpenGLEStateFreeTypeWebKitSGLSSLlibcAndroid运行时包括核心库和Dalvik虚拟机,前者既兼容了大多数Java语言所需要调用的功能函数,又包括了Android的核心库,比如android.osandroid.netandroid.media等等。后者是一种基于寄存器的java虚拟机,Dalvik虚拟机主要是完成对生命周期的管理、堆栈的管理、线程的管理、安全和异常的管理以及垃圾回收等重要功能。不过,最新的AndroidL 5.0 将彻底抛弃Dalvik虚拟机,改用ART模式。

Dalvik模式的缺点:

在Dalvik虚拟机中,因此应用程序每次运行的时候,一部分代码都需要重新进行编译,这过程需要消耗一定的时间和降低应用的执行效率,最明显的便是拖延了应用的启动时间和降低运行速度。

ART模式(Android Runtime)的优点:

通过在安装应用程序时,自动对程序进行代码预读取编译(可能比较耗时,占用更多ROM内存),让程序直接编译成机器语言,免去了Dalvik模式要时时转换代码,实现高效率、省电、占用更低的系统内存、手机运行流畅。

d) Linux内核

    Android核心系统服务依赖于Linux2.6内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型。Linux内核也是作为硬件与软件栈的抽象层。驱动:显示驱动、摄像头驱动、键盘驱动、WiFi驱动、Audio驱动、flash内存驱动、BinderIPC)驱动、电源管理等。

 

Android 开源框架

在下面的图中,绿色的大部分组件是基于Apache许可证开源,其余基于GPLLGPLBSD

 

Android 标准库


3)    通信基石 – Binder模式

Linux中,是以进程为单位分配和管理资源的。出于保护机制,一个进程不能直接访问另一个进程的资源,也就是说,进程之间互相封闭

IPC机制种类:

1-采用命名管道(named  pipe

2-消息队列(message queue

3- 信号(signal                

4-共享内存(share memory

5 - Socket

 

Android终端上的应用软件的通信几乎看不到这些IPC通信方式,取而代之的是Binder方式。

 

Binder通信机制简介


Binder使用Client-Server通信方式:一个进程作为Server提供诸如视频/音频解码,视频捕获,地址本查询,网络连接等服务;多个进程作为ClientServer发起服务请求,获得所需要的服务。要想实现Client-Server通信据必须实现以下两点:

 

,server 必须有确定的访问接入点或者说地址来接受Client的请求,并且Client可以通过某种途径获知Server的地址

,是制定Command- Reply协议来传输数据。例如在网络通信中Server的访问接入点就是Server主机的IP地址+端口号,传输协议为TCP协议。对Binder而言,Binder可以看成Server提供的实现某个特定服务的访问接入点, Client通过这个地址Server发送请求来使用该服务;对Client而言,Binder可以看成是通向Server的管道入口,要想和某个 Server通信首先必须建立这个管道并获得管道入口

 

为啥新发明一个Binider通信机制

1,复杂度

 也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。

2,传输性能

socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。

消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。

共享内存虽然无需拷贝,但控制复杂,难以使用

 

数据拷贝次数比较图

IPC进程间通信类型
数据拷贝次数
共享内存 0
Binder 1
Socket/管道/消息队列 2

3,安全性考虑

Android作为一个开放式,拥有众多开发者的的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统IPC没有任何安全措施,完全依赖上层协议来确保。

 

首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。

 

其次传统IPC访问接入点是开放的,无法建立私有通道。比如命名管道的名称,system V的键值,socketip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接



Binder通信模型

  • Binder框架定义了四个角色:ServerClientServiceManager(以后简称SMgr)以及驱动。

  • 其中 ServerClientSMgr运行于用户空间,驱动运行于内核空间。这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。

     

    Android进程间通信的底层,都是靠binder驱动传输信息, 如图:



第一步,ServerBinder实体登记

  • DNS类似,SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对ServerBinder实体的引用。注册了名字的Binder叫实名Binder,就象每个网站除了有IP地址外都有自己的网址

  • Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给 SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。驱动为这个穿过进程边界的Binder创建位于内核中的实体节点以及 SMgr对实体的引用,将名字及新建的引用传递给SMgrSMgr收数据包后,从中取出名字和引用填入一张查找表中。

  •  

第二步,Client获取Binder实体

  • ServerSMgr注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。Client也利用保留的0号引用向SMgr请求访问某个Binder:我申请获得名字叫张三的Binder的引用。

  • SMgr收到这个连接请求,从请求数据包里获得Binder的名字,在查找表里找到该名字对应的条目,从条目中取出Binder的引用,将该引用作为回复发送给发起请求的Client。从面向对象的角度,这个Binder对象现在有了两个引用:一个位于SMgr中,一个位于发起请求的Client中。

  • 如果接下来有更多的Client请求该Binder,系统中就会有更多的引用指向该Binder,就象java里一个对象存在多个引用一样。而且类似的这些指向Binder的引用是强类型,从而确保只要有引用 Binder实体就不会被释放掉。。

Binder通信机制原理图

J2EE和Android两种RPC的比较:



4)    消息队列(MessageQueue,Looper, Handler)

  • 处理多线程的时候,Android继承了java的消息队列机制。

  • Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。

     

     

消息队列里对象的数量对比图


Android消息队列运行机制原理图



5)    Framework启动过程: zygote进程和system进程

android中,大部分的应用程序进程都是由zygote来创建的,为什么用大部分,因为还有一些进程比如系统引导进程、init进程等不是有zygote创建的。相反,zygote还是在init进程之后才被创建的。

注:init进程是盘古开天地级别的进程。

zygoteandroid中主要有两个作用:

建立运行时环境并启动虚拟机,

为应用程序创建DVM进程。


    1. 启动SystemServer

    2. 启动应用进程:

       

Zygote进程运行示意图



 

1SystemService的启动是在Zygote进程创建好后进行的,并且由Zygote进程建立好DVM运行环境,加载ZygoteInitmain函数,最终调用Zygote的本地方法forkSystemServer,并执行linuxfork方法创建SystemServer进程。

 

2,应用程序的进程也是由Zygote创建的,在ActivityManagerService中的startProcessLocked中调用了Process.start()方法。并通过连接调用Zygotenative方法forkAndSpecialize,执行fork任务

 

 ActivityThread启动过程简要序列图


6)    包管理服务PackageManagerService

PackagemanagerService主要管理apk,其实就是管理其中的组件等,ActivieyService,从apk中解析其中的组件,保存到相关结构中,以使得后面可以通过相关的接口可以查询系统安装组件,apk的安装,卸载,删除都是由PackageManagerService负责的。

简言之:PMS 掌管APK生死,手里有本生死簿,类于阎王。

7)    第一个应用程序进程的启动过程

启动过程简要序列图

8)    AMS活动管理, WMS窗口管理, View系统的工作原理

android内核三大核心成员介绍:

1WMSWindowManager Service. Android上发生的事件,例如,触屏,按钮什么的都是由WMS获取的。并且WMS负责了窗口的显示和控制。


2AMSActivityManager Service. 总共有三部分的功能。
      1.activity的管理调度,但是只是在全局负责activity的管理和组织,任何activty的启动,都需要提前通知AMS,并由其进行调度但是不干涉activity内部的东西
      2.内存管理,有的时候,activity过多,可能会导致内存不够,AMS会根据内存情况,决定杀死某个 activity
     3.进程管理,AMS会提供API供用户查询当前activity的进程信息。



另外包括了两个消息处理的类KeyQInputDispatcherThread,前者是WMS的内部类,当它有一个对象建立的时候,将会监听UI上所有的用户操作,包括触屏,按键等,并且把消息放到队列当中,等待应用的调用。后者的话主要负责从前者放入的消息队列(QueueEvent)当中获取相应的消息并且以一定规则予以消息的过滤,并且发放到相应的应用程序当中,类的作用可以顾名思义。

 

(3)View
View是什么了,每个人都有自己的理解。在Android的官方文档中是这样描述的:这个类表示了用户界面的基本构建模块。一个View占用了屏幕上的一个矩形区域并且负责界面绘制和事件处理。View是用来构建用户界面组件(ButtonTextfields等等)的基类。ViewGroup子类是各种布局的基类,它是个包含其他View(或其他ViewGroups)和定义这些View布局参数的容器。

 

整个Android生态系统工作原理概述

  • 客户端中的线程

  • 包含有Activity的客户端程序至少包含3个线程,(每个Binder对应一个线程)

  • 1UI主线程

  • 2ApplicationThread对象(继承自Binder(负责AmSIPC调用)

  • 3ViewRoot.W对象(继承自Binder        (负责WmSIPC调用)


Android生态系统工作原理图:


分三步讲解整个过程:

apk程序的运行过程 () 前期准备

  • (看上面大图的中上角,或者看下面的局部截图

  • 首先,ActivityThreadmain()函数开始执行,调用prepareMainLooper()UI线程创建一个消息队列(MessageQueue)。

  •  然后创建一个ActivityThread对象,在ActivityThread的初始化代码中会创建一个HHandler)对象和一个ApplicationThreadBinder)对象。其中Binder负责接收远程AmSIPC调用,接收到调用后,则通过Handler把消息发送到消息队列中,UI主线程会异步的从消息队列中取出消息并执行相应的操作,比如start stop pause等。

  • 接着UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断的从消息队列中读取并处理消息。



apk程序的运行过程 ()启动Activity

  • (看上面大图的中间部分,或者看下面的局部截图)

  • ActivityThread接收到AmS发送start某个Activity后,就会创建指定的Activity对象,Activity又会创建PhoneWindow——>DecorView——>创建相应的View或者ViewGroup

  • 创建完成后,Activity需要把创建好的界面显示到屏幕上,于是调用WindowManager类,后者于是创建一个ViewRoot对象,该对象实际上创建了ViewRoot类和W类,创建ViewRoot对象以后,WindowManager再调用WmS提供的远程调用接口完成添加一个窗口并显示到屏幕上。



apk程序的运行过程() 响应用户屏幕操作

  •  (看上面大图最左侧,或者看下面的局部截图)

  • 接下来,用户开始在程序界面上操作,KeyQ线程不多把用户消息存储到QueueEvent队列中,InputDispatcherThread线程逐个取出消息,然后调用WmS中的相关函数处理该消息,当WmS发现该消息属于客户端某个窗口时,就会调用相应的窗口W接口。

  •  W类是一个Binder,负责接收WmSIPC调用,并把调用消息传递给ViewRootViewRoot再把消息传递给UI主线程ActivityThreadActivityThread解析该消息并作相应的处理,在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理该消息,则可以把该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后在传递给Activity

     

     


9)    总结

本文仅从总体概念和基本原理上,介绍了Android系统的基本架构、核心功能组件和工作原理,由于篇幅所限,不可能就每章每点都详细讲解,只是蜻蜓点水,一掠而过,只希望能激发初学者的好奇心,通过本文所撕开的Android外衣的一角,让你窥到一点秘密,激起你对Android的兴趣。如果想继续深入了解Android的深层原理,还需要大家一起研究学习讨论。让我们一起,继续向Android的最高殿堂前进!

 

—— 空谷幽兰 2014-7-7


更多相关文章

  1. 初遇Android——跨进程使用Service
  2. 有关Android线程的学习
  3. Asynchronous HTTP Requests in Android(安卓)Using Volley
  4. Android中对Handle机制的理解
  5. Android(安卓)IPC 通讯机制源码分析
  6. 探究Android异步消息的处理之Handler详解
  7. Android(安卓)跨进程通信(IPC)机制的探索与研究
  8. Android中Handler源码解析(一)
  9. android 退出程序三种方法及两种形式

随机推荐

  1. JS实战练习:选项卡、在线相册、轮播图、购
  2. 详解PHP使用OSS上传文件
  3. Java杂谈之重复代码是什么
  4. JavaScript实现下拉菜单的显示隐藏
  5. 华纳负责人yy988680
  6. PHP实现根据数组某个键值大小进行排序的
  7. 解构赋值及其在函数传参中的应用
  8. dataset与classlist的使用案例
  9. textarea高度自适应
  10. 自学WEB前端