初步认识Android系统框架 今天我希望通过认识Android系统框架,来了解Android运作并且确定一下步学习的方向。 从上图可知在大的方面分Android可以分为三个部分:应用部分,核心部分和底层部分。每个部分分别对应从上至下的三层。 一 逐层介绍 1. 应用层 包括手机的系统应用和第三方应用,第三方应用是基于Android SDK(software development kit)进行开发的,收到SDK接口的约束。而预装的系统应用,可以调用整个框架层的接口和模块,其中很多接口在SDK中是被影藏的。因此系统应用比第三方应用具有更多的权利。 如何在Android中使用C/C++语言?我们知道Android的应用都是基于Java开发出来的,但是在处理对效率要求较高的比如 游戏中进行大规模的运算和图形处理,以及使用开源c/c++类库。通过java难以实现,因此在Android开发中,开发者允许使用c/c++来实现底层模块,但是要提供JNI(java native Interface)接口与上层java实现进行交互,然后利用Android提供的交叉编译工具生成类库并添加到应用中。 可是程序员如何调用特定的系统功能?在Android中提供了NDK(Native Development Kit),它由c/c++的一些接口构成,这样程序员就可以绕过框架层,直接使用Android系统的特定类库。 注意:在Android上,程序员通常只能使用C/C++编写功能类库,而不是整个应用,因为诸如界面绘制(xml)、进程调度等核心机制是部署在框架层并通过java来实现的。从Android2.3开始,新增了android.app.NativeActivity类,他是用过调用预定义的JNI接口来实现的。开发者可以基于DNK,通过C/C++语言来实现具体功能。 2. 框架层 框架层由多个系统服务构成,包括:组件管理服务, 窗口管理服务,安装包管理服务,地理信息管理服务,电源 电话管理服务,等等。所有的服务都寄宿在系统核心进程中,在运行时,每个服务都占据一条独立的线程,彼此通过进程间的通信机制(Inter-Process Communication, IPC)发送消息和传递数据。(有待考证是线程还是进程) 对于开发者而言,框架层最直观的就是SDK,它通过一系列的java功能模块来实现应用所需的功能。因此,对于程序员关注SDK的变迁是很有必要的事情,程序员要查看和关注每次新SDK出炉时,哪些老的接口被调整或抛弃,和新增了哪些新的接口和功能。来检测应用的兼容性,并采取相因的策略去适应这些变化。 从系统设计的角度来看,Android期望框架层是所有应用运行的核心,参与到应用层的每一次操作当中,并进行全局的统筹。因为Android最大的特征就是基于组件化的设计方式。每个应用都有若干个组件,但是组件之间是不会建立通信通道的,而是通过框架层的组件管理服务(Activity Manager),集中地调度和传递消息。这样就相当于在组件之间加了一个中间层,该层了解所有组件的状况,可以更智能的进行协调,从而提升系统的灵活性。 3. 运行时 和Java程序运行平台一样,为了实现java程序在运行阶段的二次编译,Android为应用提供了运行时的支撑。 Android的运行时有java核心库和java虚拟机Dalvik共同构成,java核心库涵盖了框架层和应用层所有要用到的基础java库,如java对象库、文件管理库、网络通信库;等等。 Dalvik是专门为Android系统打造的java虚拟机,负责动态解析执行应用程序、分配空间、管理对象的生命周期等工作。如果说框架层是安卓的大脑,决定了应用的设计特征,那么,Dalvik就是心脏,为安卓的应用提供动力,决定他们的执行效率。 Dalvik和J2ME虚拟机对比,J2ME虚拟机是为低端设备而设计的, 而Dalvik是专门为高端设备而优化设计的。Dalvik没有采用基于栈的虚拟机架构,而是才用了基于寄存器的虚拟机架构设计。通常来说,栈类型的虚拟机对硬件依赖小,生成的应用更节约空间,可以适配更多的低端设备;基于寄存器类型的虚拟机,对硬件的门槛会更高一些,编译出的应用可能占用更多的存储空间,但是执行效率高,更能够发挥高端硬件(CPU)的能力。 Dalvik产出软件安装包(apk),Dalvik没有沿用java的二进制码(java Bytecode)作为一次编译的中间文件,而是应用了新的二进制格式文件.dex;在安卓编译过程中,先生若干个.class文件,然后统一转换成一个.dex文件,在转换过程中,Android会对部分.class文件中的指令做转义,使用Dalvik特有的指令集OpCodesl来转换,提高执行效率。同时,.dex会整合多个.class文件中的重复信息,并对冗余部分做全局的优化和调整,合并重复的常量定义,以节约常量池耗费的控件。最终结果.dex文件通常比.class打包的.jar更精简。 4. 核心类库 核心类库由一系列的二进制动态库共同构成,通常使用C/C++进行开发。于框架层相比,核心类库不能独立的运行于独立的线程中,而需要被系统服务加载到其进程空间里,通过类提供的JNI接口进行调用。核心类库中包含SQLite,libc, WebKit, OpenGL......。 核心类库的来源有两种,一种原生类库,Android为了提高框架层的执行效率,使用C/C++来实现它的一写性能关键模块,比如:资源管理模块,基础算法模块,等等。 另一种第三方类库,大部分是一些优秀的开源项目的移植,他们是Android能够提供丰富功能的保障,如:Android的多媒体处理,依赖于开源项目OpenCORE的支持,浏览器控件的核心实现,是从Webkit移植过来的;Android会为所有移植而来第三方类库封装一层JNI接口,以供框架层调用。 为了帮助游戏和图形图像处理等领域的开发者搭建更好高效的应用,Android将数学库、OpenGL库等核心类库以NDK的形式提供给开发者,开发者可以利用NDK更高效的构建算法,进行图形图像的绘制。从实践的角度看,开发者只要能获取到底层类库的头文件信息,开发者就可以逾越NDK的界限,但是这样很不安全,Android版本变迁时,可能会修改或替换一些类库接口或实现,这样会导致依赖于这些类库的应用无法使用。而NDK提供的都是稳定的类库实现,不会再做修改。 5. 硬件抽象层和Linux内核 从运行的角度来看,Android只是在Linux系统上的一些进程,并不是完整的系统,离开了Linux就像鱼离开了水,无法运行。 Linux之于Android的最大价值在于强大的可移植性。Linux可以运行在各样的芯片架构和硬件环境下,从Android也是一样,其次Linux像一座桥梁,将Android的上层实现与底层硬件连接起来,使他们可以不必直接耦合。 而硬件抽象层(Hardware Abstract Layer, HAL),是Android提供给厂商的一套接口标准,它为框架层提供接口支持。 本文到此结束,如有错误,欢迎指正!