浅谈Android之系统概述

先来看下Android SDK第一篇文章 What is android中一张描述Android系统结构的图:



基于这张图,可以很清晰的看出android的框架结构,最顶上是各种各样的应用,应用需要framework中各种各样的服务做支撑,然后就是各种各样的库文件(.so)被framework代码所引用,用来跟低层的各种Drivers做数据通信,从而实现对应的功能。


相信很多人看了上面这张图后,会有各种各样的问题,比如:

1):framework是啥?它的代码跑在哪个进程里头?

2):APP跟framework中的各种服务是如何进行通讯的?

3):虚拟机是如何被初始化的,JAVA和framework对应的代码资源(.JAR)是如何被加载的?

4): android的很多Linux原生服务(未包含虚拟机),比如Init,Servicemanager,Mediaserver,Surfaceflinger,Bootanimation,Ril daemon等等,它们跟Android的一些APP是如果建立关联的?


这些问题,光看结构图肯定无法解答,因为它是静态的,接下去看下面这张图:


从系统运行的角度来看,操作系统分内核空间和用户空间,分别对应图中的系统内核和应用程序,内核跑着Linux系统内核和各种驱动代码,当内核初始化结束后,Linux会启动用户空间的初始进程(应用)Init;

这两个空间内部的代码是没有权限直接访问对方内部数据的,所以,只能通过系统设备间接访问,这就需要系统内核暴露各种各样的设备以便应用程序能够通过它们来访问对应的硬件设备和内核功能;在Linux系统,设备即文件,所以应用程序就可以以通用的I/O操作来跟设备做数据交互,如果需要定义更加复杂的交互协议,可以使用IOCTL。

Init被启动后,它会解析init.rc,然后fork出各种各样的Linux原生程序,在默认情况下,Linux原生程序存放路径为:

/system/bin

程序运行所需的库文件存放路径为:

/system/lib

注意,上面这些程序都是原生的,那Android的呢?在哪里?Android程序跟Linux原生程序最大的区别是,它有虚拟机,并且进程地址空间中包含有虚拟机运行所需的jdk和android framework代码资源,所以,系统必须要创建一个进程来创建虚拟机并加载代码资源,这个进程就是Zygote,同样的,它也是从init fork出来的子进程。

Zygote启动后,它会创建虚拟机,然后将代码资源加载进来,android代码资源默认存放路径为:

/system/framework

虚拟机根据bootclasspath环境变量所配置的值加载相应的JAR。

Zygote启动结束后,它会创建一个server socket,然后listen,等待client与其连接后fork出对应的子进程,也就是各种各样的Android应用程序。

同时Zygote也会fork出它的第一个子进程System server,即Android的核心服务进程。

SystemServer起来后,会初始化各种各样的系统服务,比如PackageManagerService,ActivityManagerService等等一系列系统服务。

最后,回到上面的第一个问题,framework是啥?它就是所有android应用要用到的代码集合,它里头涉及到系统服务相关的代码,最终会被System server所执行,同样的,很多应用层相关的代码,会被各种Android APP所执行。

由于这篇文章重点介绍UI相关内容,所以上头的内容就不扩展开来讲了。

上头说过了,系统内核和应用程序通过内核设备进行通信,那应用程序间呢?比如一个Android APP是如何与SurfaceFlinger或System server建立高效的进程间数据通信的?大家都知道,Android使用的是Binder通信机制,它支持远程过程调用功能(RPC),所以在Android上写进程间通信代码就会异常简单,方式跟调用一个本地函数无异。

Binder是Android的基础,系统层代码中充斥着大量的Binder通信代码,所以在详细分析系统层代码之前,强烈建议先了解下Binder的实现原理。


后续文章都基于Android 5.1系统源码来分析,由于本人水平有限,难免会存在错误或者描述不准确的地方,欢迎大家指正!!

发布了46 篇原创文章 · 获赞 25 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/zhejiang9/article/details/55095542