深入理解Android 5 源代码
上QQ阅读APP看书,第一时间看更新

2.2 分析Android源代码结构

获得Android 5.0源代码后,源代码的全部工程分为以下3个部分。

· Core Project:核心工程部分,这是建立Android系统的基础,被保存在根目录的各个文件夹中。

· External Project:扩展工程部分,可以使其他开源项目具有扩展功能,被保存在“external”文件夹中。

· Package:包部分,提供了Android的应用程序、内容提供者、输入法和服务,被保存在“package”文件夹中。

在本节的内容中,将详细讲解Android 5.0源代码的目录结构。

2.2.1 总体结构

无论是Android 1.5还是Android 5.0,各个版本的源代码目录基本类似。在里面包含了原始Android的目标机代码、主机编译工具和仿真环境。解压缩下载的Android 5.0源代码包后,可以看到第一级目录有多个文件夹和一个Makefile文件,如图2-14所示。

图2-14 下载的Android 5.0源代码

如果是编译后的源代码目录,则会增加一个out文件夹,用来存放编译产生的文件。Android 5.0第一级别目录结构的具体说明如表2-1所示。

表2-1 Android 5.0源代码的根目录

由此可见,通过对源代码中根目录的每个文件夹的功能的介绍,可以看出源代码按功能分类还是非常清晰的,可以分为系统代码、工具、文档、开发环境、虚拟机、配置脚本和编译脚本等类别。并且也可以看出涉及的内容比较庞大和复杂,源代码分析工作需要多方面的理论和实践知识。

2.2.2 应用程序部分

应用程序主要是UI界面的实现,广大开发者基于SDK上开发的一个个独立的APK包,都是属于应用程序这一层的,应用程序在Android系统中处于最上层的位置。源代码结构中的packages目录用来实现系统的应用程序,packages的目录结构如下所示。

packages /
├—— apps //应用程序库
|   ├—— BasicSmsReceiver           //基础短信接收
|   ├—— Bluetooth                  //蓝牙
|   ├—— Browser                    //浏览器
|   ├—— Calculator                 //计算器
|   ├—— Calendar                   //日历
|   ├—— Camera                     //照相机
|   ├—— CellBroadcastReceiver      //单元广播接收
|   ├—— CertInstaller              //被调用的包,在Android中安装数字签名
|   ├—— Contacts                   //联系人
|   ├—— DeskClock                  //桌面时钟
|   ├—— Email                      //电子邮件
|   ├—— Exchange                   //Exchange服务
|   ├—— Gallery                    //图库
|   ├—— Gallery2                   //图库2
|   ├—— HTMLViewer                 //HTML查看器
|   ├—— KeyChain                   //密码管理
|   ├—— Launcher2                  //启动器2
|   ├—— Mms                         //彩信
|   ├—— Music                      //音乐
|   ├—— MusicFX                    //音频增强
|   ├—— Nfc                         //近场通信
|   ├—— PackageInstaller           //包安装器
|   ├—— Phone                      //电话
|   ├—— Protips                    //主屏幕提示
|   ├—— Provision                  //引导设置
|   ├—— QuickSearchBox             //快速搜索框
|   ├—— Settings                   //设置
|   ├—— SoundRecorder              //录音机
|   ├—— SpareParts                 //系统设置
|   ├—— SpeechRecorder             //录音程序
|   ├—— Stk                         //sim卡相关
|   ├—— Tag                         //标签
|   ├—— VideoEditor                //视频编辑
|   └—— VoiceDialer                //语音编号
├—— experimental                    //非官方的应用程序
|   ├—— BugReportSender            //Bug的报告程序
|   ├—— Bummer
|   ├—— CameraPreviewTest          //照相机预览测试程序
|   ├—— DreamTheater
|   ├—— ExampleImsFramework
|   ├—— LoaderApp
|   ├—— NotificationLog
|   ├—— NotificationShowcase
|   ├—— procstatlog
|   ├—— RpcPerformance
|   └—— StrictModeTest
├—— inputmethods                    //输入法
|   ├—— LatinIME                   //拉丁文输入法
|   ├—— OpenWnn                    //OpenWnn输入法
|   └—— PinyinIME                  //拼音输入法
├—— providers                       //提供器
|   ├—— ApplicationsProvider       //应用程序提供器,提供应用程序所需的界面
|   ├—— CalendarProvider           //日历提供器
|   ├—— ContactsProvider           //联系人提供器
|   ├—— DownloadProvider           //下载管理提供器
|   ├—— DrmProvider                //数据库相关
|   ├—— GoogleContactsProvider     //Google联系人提供器
|   ├—— MediaProvider              //媒体提供器
|   ├—— TelephonyProvider          //彩信提供器
|   └—— UserDictionaryProvider     //用户字典提供器
├—— screensavers                    //屏幕保护
|   ├—— Basic                      //基本屏幕保护
  |   ├—— PhotoTable            //照片方格
  |   ├—— WebView               //网页
└—— wallpapers                      //墙纸
├—— Basic                       //系统内置墙纸
├—— Galaxy4                     //S4内置墙纸
├—— HoloSpiral                  //手枪皮套墙纸
├—— LivePicker
├—— MagicSmoke
├—— MusicVisualization
├—— NoiseField
└—— PhaseBeam

通过上面的目录结构可以看出,package目录主要存放的是与Android系统应用层相关的内容,包括应用程序相关的包或者资源文件,其中包括系统自带的应用程序,及第三方开发的应用程序,还有屏幕保护和墙纸等应用,所以源代码中package目录对应着系统的应用层。

2.2.3 应用程序框架部分

应用程序框架是Android系统中的核心部分,也就是SDK部分,它会提供接口给应用程序使用,同时应用程序框架又会和系统服务、系统程序库、硬件抽象层有关联,所以其作用十分重大,应用程序框架的实现代码大部分都在/frameworks/base和/framwworks/av目录下,/frameworks/base的目录结构如下所示。

frameworks/base
├—— api             //全是XML文件,定义了API
├—— cmds            //Android中的重要命令(am、app_proce等)
├—— core            //核心库
├—— data            //声音字体等数据文件
├—— docs            //文档
├—— drm             //数字版权管理
├—— graphics       //图形图像
├—— icu4j           //用于解决国际化问题
├—— include        //头文件
├—— keystore       //数字签名证书相关
├—— libs            //库
├—— location       //地理位置
├—— media           //多媒体
├—— native         //本地库
├—— nfc-extras     //NFC相关
├—— obex            //蓝牙传输
├—— opengl         //opengl相关
├—— packages       //设置、TTS、VPN程序
├—— policy         //锁屏界面相关
├—— sax             //XML解析器
├—— services       //Android的服务
├—— telephony      //电话相关
├—— test-runner    //测试相关
├—— tests           //测试相关
├—— tools           //工具
├—— voip            //可视通话
└—— wifi            //无线网络

以上这些文件夹包含了应用程序框架层的大部分代码,正是这些目录下的文件构成了Android的应用程序框架层,暴露出接口给应用程序调用,同时衔接系统程序库和硬件抽象层,形成一个由上至下的调用过程。在/frameworks/base目录下也涉及系统服务,程序库中的一些代码,我们将在后面的两个小节中再详细分析。

2.2.4 系统服务部分

在2.2.2中介绍了应用程序框架层的内容,了解到大部分的实现代码保存在“/frameworks/base”目录下。其实在这个目录中还有一个名为“service”的目录,里面的代码是用于实现Android系统服务的。接下来将详细介绍service目录下的内容,其目录结构如下所示。

rameworks/base/services
—— common_time          //时间、日期相关的服务
├—— input                //输入系统服务
├—— java                 //其他重要服务的Java层
├—— jni                  //其他重要服务的JNI层
└—— tests                //测试相关

其中java和jni两个目录分别是一些其他的服务的Java层和JNI层实现,Java目录下更详细的目录结构以及其他Android系统服务的说明如下所示。

frameworks/base/services/java/com/android/server
├—— accessibility
├—— am
├—— connectivity
├—— display
├—— dreams
├—— drm
├—— input
├—— location
├—— net
├—— pm
├—— power
├—— updates
├—— usb
├—— wm
├—— AlarmManagerService.java            //闹钟服务
├—— AppWidgetService.java                //应用程序小工具服务
├—— AppWidgetServiceImpl.java
├—— AttributeCache.java
├—— BackupManagerService.java           //备份服务
├—— BatteryService.java                  //电池相关服务
├—— BluetoothManagerService.java        //蓝牙
├—— BootReceiver.java
├—— BrickReceiver.java
├—— CertBlacklister.java
├—— ClipboardService.java
├—— CommonTimeManagementService.java    //时间管理服务
├—— ConnectivityService.java
├—— CountryDetectorService.java
├—— DevicePolicyManagerService.java
├—— DeviceStorageMonitorService.java    //设备存储器监听服务
├—— DiskStatsService.java                //磁盘状态服务
├—— DockObserver.java                    //底座监视服务
├—— DropBoxManagerService.java
├—— EntropyMixer.java
├—— EventLogTags.logtags
├—— INativeDaemonConnectorCallbacks.java
├—— InputMethodManagerService.java      //输入法管理服务
├—— IntentResolver.java
├—— IntentResolverOld.java
├—— LightsService.java
├—— LocationManagerService.java         //地理位置服务
├—— MasterClearReceiver.java
├—— MountService.java                    //挂载服务
├—— NativeDaemonConnector.java
├—— NativeDaemonConnectorException.java
├—— NativeDaemonEvent.java
├—— NetworkManagementService.java       //网络管理服务
├—— NetworkTimeUpdateService.java
├—— NotificationManagerService.java     //通知服务
├—— NsdService.java
├—— PackageManagerBackupAgent.java
├—— PreferredComponent.java
├—— ProcessMap.java
├—— RandomBlock.java
├—— RecognitionManagerService.java
├—— SamplingProfilerService.java
├—— SerialService.java                   //NFC相关
├—— ServiceWatcher.java
├—— ShutdownActivity.java
├—— StatusBarManagerService.java        //状态栏管理服务
├—— SystemBackupAgent.java
├—— SystemServer.java
├—— TelephonyRegistry.java
├—— TextServicesManagerService.java
├—— ThrottleService.java
├—— TwilightCalculator.java
├—— TwilightService.java
├—— UiModeManagerService.java
├—— UpdateLockService.java               //锁屏更新服务
├—— VibratorService.java                 //振动服务
├—— WallpaperManagerService.java        //壁纸服务
├—— Watchdog.java                        //看门狗
├—— WifiService.java                     //无线网络服务
└—— WiredAccessoryManager.java          //无线设备管理服务

从上面的文件夹和文件可以看出,Android中涉及的服务种类非常多,包括界面、网络、电话等核心模块基本上都有其专属的服务,这些是属于系统级别的服务,这些系统服务一般都会在Android系统启动的时候加载,在系统关闭的时候结束,受到系统的管理,应用程序并没有权力去打开或者关闭,它们会随着系统的运行一直在后台运行,供应用程序和其他的组件使用。

另外,在frameworks/av/下面也有一个services目录,这个目录下存放的是音频和照相机的服务的实现代码,目录结构如下所示。

frameworks/av/services
 ├—— audioflinger         //音频管理服务
 └—— camera               //照相机的管理服务

这个av/services目录下的文件主要是用来支持Android系统中的音频和照相机服务的,这是两个非常重要的系统服务,开发应用程序时会经常依赖这两个服务。

2.2.5 系统程序库部分

Android的系统程序库类型非常多,功能也非常强大,正是有了这些程序库,Android系统才能运行多种多样的应用程序。在接下来的内容中,笔者挑了一些很常用也是很重要的系统程序库来分析它们在源代码中所处的位置。

(1)系统C库

Android系统采用的是一个从BSD继承而来的标准的系统函数库bionic,在源代码根目录下有这个文件夹,其目录结构如下所示。

bionic/
├—— libc            //C库
├—— libdl           //动态链接库相关
├—— libm            //数学库
├—— libstdc++      //C++实现库
├—— libthread_db   //线程库
├—— linker         //连接器相关
└—— test            //测试相关

(2)媒体库

Anroid 2.3之后的媒体库由Stragefright实现,同时Android也自带了一些音视频的管理库,用于管理多媒体的录制、播放、编码和解码等功能。Android多媒体程序库的实现代码主要在/frameworks/av/media目录下,其目录结构如下所示。

frameworks/av/media/
├—— common_time               //时间相关
├—— libeffects                //多媒体效果
├—— libmedia                  //多媒体录制,播放
├—— libmedia_native           //里面只有一个Android.mk,用来编译native文件
├—— libmediaplayerservice     //多媒体播放服务的实现库
├—— libstagefright            //stagefright的实现库
├—— mediaserver               //跨进程多媒体服务
└—— mtp                       //mtp协议的实现(媒体传输协议)

(3)图层显示库

Android中的图层显示库主要负责对显示子系统的管理,负责图层的渲染、叠加、绘制等功能,提供了2D和3D图层的无缝融合,是整个Android系统显示的“大脑中枢”,其代码在/frameworks/native/services/surfaceflinger/目录下,其目录结构如下所示。

frameworks/native/services/surfaceflinger/
├—— DisplayHardware           //显示底层相关
├—— tests                     //测试
├—— Android.mk                //MakeFile文件
├—— Barrier.h
├—— Client.cpp                //显示的客户端实现文件
├—— Client.h
├—— clz.cpp
├—— clz.h
├—— DdmConnection.cpp
├—— DdmConnection.h
├—— DisplayDevice.cpp         //显示设备相关
├—— DisplayDevice.h
├—— EventThread.cpp           //消息线程
├—— EventThread.h
├—— GLExtensions.cpp          //opengl扩展
├—— GLExtensions.h
├—— Layer.cpp                 //图层相关
├—— Layer.h
├—— LayerBase.cpp             //图层基类
├—— LayerBase.h
├—— LayerDim.cpp              //图层相关
├—— LayerDim.h
├—— LayerScreenshot.cpp       //图层相关
├—— LayerScreenshot.h
├—— MessageQueue.cpp          //消息队列
├—— GLExtensions.h
├—— MessageQueue.h
├—— MODULE_LICENSE_APACHE2    //证书
├—— SurfaceFlinger.cpp        //图层管理者,图层管理的核心类
├—— SurfaceFlinger.h
├—— SurfaceTextureLayer.cpp   //文字图层
├—— SurfaceTextureLayer.h
├—— Transform.cpp
└—— Transform.h

(4)网络引擎库

网络引擎库主要是用来实现Web浏览器的引擎,支持Android的Web浏览器和一个可嵌入的Web视图,这个是采用第三方开发的浏览器引擎Webkit实现的,Webkit的代码在/external/webkit/目录下,其目录结构如下所示。

external/webkit/
├—— Examples                  //Webkit例子
├—— LayoutTests               //布局测试
├—— PerformanceTests          //表现测试
├—— Source                    //Webkit源代码
├—— Tools                     //工具
├—— WebKitLibraries           //Webkit用到的库
├—— Android.mk                //Makefile
├—— bison_check.mk
├—— CleanSpec.mk
├—— MODULE_LICENSE_LGPL       //证书
├—— NOTICE
└—— WEBKIT_MERGE_REVISION     //版本信息

(5)3D图形库

Android中的3D图形渲染是采用Opengl来实现的,Opengl是开源的第三方图形渲染库,使用该库可以实现Android中的3D图形硬件加速或者3D图形软件加速功能,是一个非常重要的功能库。从Android 5.0开始,支持最新、最强大的OpenGL ES 3.1。其实现代码在/frameworks/native/opengl中,其目录结构如下所示。

frameworks/native/opengl/
├—— include              //Opengl中的头文件
├—— libagl               //在mac os上的库
├—— libs                 //Opengl的接口和实现库
├—— specs                //Opengl的文档
├—— tests                //测试相关
└—— tools                //工具库

(6)SQLite

SQLite是Android系统自带的一个轻量级关系数据库,其实现源代码已经在网上开源。SQLite的优点是操作简单方便,运行速度较快,占用资源较少等特点,比较适合在嵌入式设备上使用。SQLite是Android系统自带的实现数据库功能的核心库,其代码实现分为Java和C两个部分,Java部分的代码在/frameworks/base/core/java/android/database,目录结构如下所示。

frameworks/base/core/java/android/database/
├—— sqlite                                     //SQLite的框架文件
├—— AbstractCursor.java                       //游标的抽象类
├—— AbstractWindowedCursor.java
├—— BulkCursorDescriptor.java
├—— BulkCursorNative.java
├—— BulkCursorToCursorAdaptor.java            //游标适配器
├—— CharArrayBuffer.java
├—— ContentObservable.java
├—— ContentObserver.java                      //内容观察者
├—— CrossProcessCursor.java
├—— CrossProcessCursorWrapper.java            //CrossProcessCursor的封装类
├—— Cursor.java                               //游标实现类
├—— CursorIndexOutOfBoundsException.java     //游标出界异常
├—— CursorJoiner.java
├—— CursorToBulkCursorAdaptor.java            //适配器
├—— CursorWindow.java                         //游标窗口
├—— CursorWindowAllocationException.java     //游标窗口异常
├—— CursorWrapper.java                        //游标封装类
├—— DatabaseErrorHandler.java                 //数据库错误句柄
├—— DatabaseUtils.java                        //数据库工具类
├—— DataSetObservable.java
├—— DataSetObserver.java
├—— DefaultDatabaseErrorHandler.java         //默认数据库错误句柄
├—— IBulkCursor.java
├—— IContentObserver.aidl                     //aidl用于跨进程通信
├—— MatrixCursor.java
├—— MergeCursor.java
├—— Observable.java
├—— package.html
├—— SQLException.java                         //数据库异常
└—— StaleDataException.java

Java层的代码主要是实现SQLite的框架和接口的实现,方便用户开发应用程序时能很简单地操作数据库,并且捕获数据库异常。

C++层的代码在/external/sqlite路径下,其目录结构如下所示。

external/sqlite/
├—— android        //Android数据库的一些工具包
└—— dist            //Android数据库底层实现

从上面Java和C部分的代码目录结构可以看出,SQLite在Android中还是有很重要的地位的,并且在SDK中会有开放的接口让应用程序可以很简单方便地操作数据库,对数据进行存储和删除。

2.2.6 硬件抽象层部分

Android的硬件抽象是各种功能的底层实现,理论上,不同的硬件平台会有不同的硬件抽象层实现,这一个层次也是与驱动层和硬件层有紧密的联系的,起着承上启下的作用,对上要实现应用程序框架层的接口,对下要实现一些硬件基本功能,以及调用驱动层的接口。需要注意的是,这一层也是广大OEM厂商改动最大的一层,因为这一层的代码与终端采用什么样的硬件平台有很大关系。源代码中存放的是硬件抽象层框架的实现代码和一些平台无关性的接口的实现。硬件抽象层代码在源代码根目录下的hardware文件夹中,其目录结构如下所示。

hardware/
├—— libhardware               //新机制硬件库
├—— libhardware_legacy        //旧机制硬件库
└—— ril                       //ril模块相关的底层实现

从上面的目录结构我们可以看出,硬件抽象层中主要是实现了一些底层的硬件库,用来实现应用层框架层中的功能,具体硬件库中有哪些内容,我们可以继续细分其目录结构,例如,libhardware目录下的结构如下:

hardware/libhardware/
├—— include                   //入口目录
├—— modules                   //dex反汇编
|   ├—— audio                 //音频相关底层库
|   ├—— audio_remote_submix  //音频混合相关
|   ├—— gralloc               //帧缓冲
|   ├—— hwcomposer            //音频相关
|   ├—— local_time            //本地时间
|   ├—— nfc                   //nfc功能
|   ├—— nfc-nci               //nfc的接口
|   ├—— power                 //电源
|   ├—— usbaudio              //USB音频设备
|   ├—— Android.mk            //Makefile
|   ├—— README.android
├—— tests                     //dex生成相关
├—— dexlist                   //dex列表
├—— dexopt                    //与验证和优化
└—— docs                      //文档

从上面的目录结构我们可以分析出,libhardware目录主要是Android系统的某些功能的底层实现,包括audio、nfc和power。

而libhardware_legacy的目录与libhardware大同小异,只是针对旧的实现方式做的一套硬件库,其目录下还有uevent、WiFi以及虚拟机的底层实现。这两个目录下的代码一般会由设备厂家根据自身的硬件平台来实现符合Android机制的硬件库。

而ril目录下存放的是无线硬件设备与电话的实现,其目录结构如下所示。

hardware/ril/
├—— include              //头文件
├—— libril               //libril库
├—— mock-ril
├—— reference-ril        //reference ril库
├—— rild                 //ril守护进程
└—— CleanSpec.mk