1.1.2 框架层

  框架层是Android系统中核心的部分,它集中体现了Android系统的设计思想。在Android之前,有很多基于Linux内核打造的移动平台。作为超越前辈的成功范例,框架层的设计正是Android脱颖而出的关键所在。

  框架层由多个系统服务(System Service)共同组成,包括组件管理服务、窗口管理服务、地理信息服务、电源管理服务、通话管理服务,等等。所有服务都寄宿在系统核心进程(System Core Process)中,在运行时,每个服务都占据一个独立的线程,彼此通过进程间的通信机制(Inter-Process Communication,IPC)发送消息和传输数据。

  应用层中的应用,时刻都在与这些系统服务打交道。每一次构造窗口、处理用户交互事件、绘制界面、获得当前地理信息、了解设备信息等操作,都是在各个系统服务的支持下实现的。

  而对于开发者而言,框架层直观的体现是SDK,它通过一系列的Java功能模块,来实现应用所需的功能。SDK的设计决定了上层应用的开发模式、开发效率及能够实现的功能范畴。因此,对于开发者而言,关注SDK的变迁是一件很有必要的事情,SDK每个新版本的诞生,都意味着一些老的接口会被调整或抛弃,另一些新的接口和功能火热出炉。开发者不但要查看和关注那些被修改的接口,来检查应用的兼容性,并采取相应的策略去适应这些变化,更重要的是,开发者还要追踪新提供的接口,寻找改进应用的机会,甚至是寻求开发新应用的可能。

  从系统设计的角度来看,Android期望框架层是所有应用运行的核心,参与到应用层的每一次操作中,并进行全局统筹。Android应用的大特征是基于组件的设计方式。每个应用都由若干个组件构成,组件和组件之间并不会建立通信信道,而是通过框架层的系统服务,集中地调度和传递消息。这样的设计方式相当于增加了一个中间层,该层了解所有组件的状况,可以更智能地进行协调,从而提升了整个系统的灵活性。

  1.1.3 运行时

  和所有的Java程序运行平台一样,为了实现Java程序在运行阶段的二次编译, Android为它们提供了运行时(Runtime)的支撑。

  Android的运行时由Java核心类库和Java虚拟机Dalvik共同构成。Java核心类库涵盖了Android框架层和应用层所要用到的基础Java库,包括Java对象库、文件管理库、网络通信库,等等。

  Dalvik是为Android量身打造的Java虚拟机,负责动态解析执行应用、分配空间、管理对象生命周期等工作。如果说框架层是整个Android的大脑,决定了Android应用的设计特征,那么,Dalvik是Android的心脏,为Android的应用提供动力,决定它们的执行效率。

  与为低端移动设备而设计的J2ME虚拟机不同,Dalvik是专门为高端设备而优化设计的。它没有采用基于栈的虚拟机架构,而是采取了基于寄存器的虚拟机架构设计。通常来说,基于栈的虚拟机对硬件的依赖程度小、生成的应用更节约空间,可以适配更多的低端设备;而基于寄存器的虚拟机,对硬件的门槛会更高一些,编译出的应用可能会耗费稍多的存储空间,但它的执行效率更高,更能够发挥高端硬件(主要指处理器)的能力。

  Dalvik没有沿用传统的Java二进制码(JavaBytecode)作为其一次编译的中间文件,而是应用了新的二进制码格式文件.dex。在Android应用的编译过程中,它会先生成若干个.class文件,然后统一转换成一个.dex文件。在转换过程中,Android会对部分.class文件中的指令做转义,使用Dalvik特有的指令集OpCodes来替换,以提高执行效率。同时,.dex会整合多个.class文件中的重复信息,并对冗余部分做全局的优化和调整,合并重复的常量定义,以节约常量池耗费的空间。这使得终得到的.dex文件通常会比将.class文件压缩打包得出的.jar文件更精简。

  为了提升Android应用的执行效率,从垃圾回收器(Garbage Collection,GC)到编译器,Dalvik一直在各个方面进行优化。经常可以听到这样的消息:“新版本的Android系统,比上一个版本的效率高了x倍。”这大都是改善Dalvik的效果。在Android 2.2中,Dalvik引入了对JIT(Just-in-time)编译的支持,将上层应用的执行效率提升了2~4倍,开启了Android发展的新篇章。

  由于对于大部分应用开发者而言,无须了解Android运行时的具体细节,因此,本书后续将不会详细介绍Android运行时的相关内容,有兴趣的读者,可以另行查阅相关资料和源代码。

  1.1.4 核心类库

  对于框架层而言,核心类库是它的“贤内助”。每一次Android系统升级,能看到的都是框架层SDK的变迁,增加了新的功能,提供了新的接口。而在这些新功能的背后,核心类库都是居功至伟。

  核心类库由一系列的二进制动态库共同构成,通常使用C/C++进行开发。与框架层的系统服务相比,核心类库不能够独立运行于线程中,而需要被系统服务加载到其进程空间里,通过类库提供的JNI接口进行调用。

  核心类库的来源主要有两种,一种是系统原生类库,Android为了提高框架层的执行效率,使用C/C++来实现它的一些性能关键模块,如:资源文件管理模块、基础算法库,等等。而另一种则是第三方类库,大部分都是对开源项目的移植,它们是Android能够提供丰富功能的重要保障,如:Android的多媒体处理,依赖于开源项目OpenCORE的支持;浏览器控件的核心实现,是从Webkit移植而来;而数据库功能,则是得益于Sqlite。Android会为所有移植而来第三方类库封装一层JNI接口,以供框架层调用。

  为了帮助游戏和图形图像处理等领域的开发者搭建更高效的应用,Android将数学函数库、OpenGL库等核心类库以NDK的形式提供给开发者,开发者可以基于NDK更高效地构建算法,进行图形图像绘制。从实践的角度看,只要能获取到底层类库的头文件信息,开发者可以逾越NDK的界限,用其他核心类库的接口进行开发。但这样做的危险之处在于兼容性差,Android在版本变迁时,可能会替换或修改一些类库接口或实现,这会导致依赖于这些类库的应用无法运行。而NDK提供的都是稳定的类库实现,不会再做修改,以保证使用NDK的应用具有向上的兼容性。

  1.1.5 硬件抽象层和Linux内核

  Android系统并不是从零开始设计的,而是搭建在Linux内核之上。狭义的Android系统,主要指的是Linux内核以上的各层,从运行的角度来看,它们只是运行在Linux系统上的一些进程,并不是完整的系统,离开了Linux的支撑,像鱼儿离开了水一样,无法运行。

  Linux之于Android大的价值,便是其强大的可移植性。Linux可以运行在各式各样的芯片架构和硬件环境下,而依托于它的Android系统,也便有了强大的可移植性。同时,Linux像一座桥梁,将Android的上层实现与底层硬件连接起来,使它们可以不必直接耦合,因此,降低了移植的难度。

  而硬件抽象层(Hardware Abstract Layer,HAL),是Android为厂商定义的一套接口标准,它为框架层提供接口支持,厂商需要根据定义的接口实现相应功能。