Android系统移植的主要目的是为了能在特定的硬件上运行Android系统。而在移植的过程中,一个重要的方面就是把握关键要点,减少工作量。首先要熟悉硬件抽象层的接口,其次要集成和复用已有的驱动程序,主要的工作量集中在对硬件抽象层的实现中。为了更好地理解和调试系统,应该适当地对硬件抽象层的调用情况有所了解。
移植过程中主要的工作可分为两个部分:Linux驱动;Android系统硬件抽象层。
Linux中的驱动工作在系统内核空间,Android系统硬件抽象层工作在用户空间,有了这两个部分的结合,就可以让庞大的Android系统运行在特定的硬件平台上。在有了特定的硬件系统之后,需要在Linux中实现该硬件的驱动程序,这些驱动程序都是Linux的标准驱动程序,在Android平台和其他Linux平台上基本是相同的。
工作主要集中在Android系统中的硬件抽象层,硬件抽象层向下调用Linux中的驱动程序,向上提供接口,供Android系统之外的其他部分调用。
在Android系统中需要移植的主要包含以下内容:
·显示部分
·用户输入部分
·多媒体编解码
·3D加速器部分
·音频部分
·视频输出部分
·摄像头部分
·电话部分
·GPS
·WiFi
·蓝牙
·传感器部分
·振动器部分
·背光部分
·实时时钟
·电池部分
Android系统中包括很多组件,并不是每一个组件都需要移植。对于一些纯软件的组件,就没有移植的必要。对于诸如浏览器引擎等一些组件,虽然需要下层网络的支持,但是并非直接为其移植网络接口,而是通过无线局域网或电话系统数据的连接来完成标准的网络接口,这类组件也不需要移植。
Android的移植可以分成以下几个主要的类型:基本图形用户界面(GUI)部分,包括显示部分和用户输入部分;与硬件相关的加速部分,包括媒体编解码和OpenGL;音视频输入输出环节,包括音频、视频输出和摄像头部分;连接部分,包括无线局域网、蓝牙、GPS;电话部分;附属部件,包括传感器、背光、振动器等。
除此之外,电源管理也是一个非常重要的移植组件,它和Android系统的各个子系统都有关系。对于大部分子系统,硬件抽象层和驱动程序都需要根据实际系统的情况实现,例如传感器部分、音频部分、视频部分、摄像头部分、电话部分。也有一些子系统,硬件抽象层是标准的,只需要实现Linux内核中的驱动程序即可,例如输入部分、振动器部分、无线局域网部分、蓝牙部分等。对于有标准的硬件抽象层的系统,有的时候通常也需要做一些配置工作。
Android系统的开发主要就是中间件的开发。由于Google已经提供了绝大部分的中间件,因此系统开发的工作主要集中在对JNI库的开发。JNI是Java应用程序访问其他语言,尤其是中低级语言的接口。通过JNI,用户可以把对性能要求高的或者与操作系统底层直接打交道的程序封装在一个库文件中,通过JNI机制进行调用。JNI的实现流程如图3-1所示。
图3-1 JNI实现流程
如果是针对通用的Android设备开发,比如手机、平板电脑等,一般把电源管理、传感器等系统独有设备的用户态驱动程序放在JNI中,由上层的电源管理应用调用。除此之外,高级视频编解码算法、压缩解压等Android自身不提供的算法,也会被封装在JNI中。
如果针对专用的Android设备开发,比如视频监控设备、图像处理设备等,一般会把OpenCV等图像处理的算法封装在JNI模块中。
应用程序是直接与用户打交道的程序。因为Android的分层特性,应用程序不与硬件或操作系统直接沟通。相反地,应用程序只与Android系统内的Java类和JNI库沟通,因而拥有良好的可移植性,能做到一次开发,处处运行。
开发Android应用程序需要使用Android SDK,该SDK可以从Android的官方网站下载。如果要使用特殊的JNI库或针对特定手机开发的Java类库,则要使用对应型号的手机SDK,或自行编译SDK。需要注意的是,非官方SDK开发的应用程序可能无法在其他平台上运行,因而推荐使用官方SDK。仅当为特定机型开发时才应使用自定义SDK。如果需要使用特定的JNI库,可以使用Android NDK,并将NDK编译生成的.so文件封装到.apk文件中。注意,.so文件不能跨平台,因此要为不同的平台编译不同的.so文件。
本书仅介绍Android系统底层的移植与开发,并不涉及Android应用开发。