QCon 全球软件开发大会(北京站)门票 9 折倒计时 4 天,点击立减 ¥880 了解详情
写点什么

Android 系统源代码情景分析:基础知识

2011 年 12 月 14 日

【编者按】移动开发领域已经成为技术社区的一大热点,InfoQ 中文站也在密切关注。本专栏旨在帮助 Android 应用开发人员更深入地了解该系统的底层架构、源码实现,以便在实际开发过程中更有效地利用 Android 系统的功能特性,达到“庖丁解牛”的境界。


目前,互联网行业正在朝着移动互联网方向强劲地发展,而移动互联网的发展离不开背后的移动平台的支撑。众所周知,如今在移动平台市场上,苹果的 iOS、谷歌的 Android 和微软的 Windows Phone 系统已经形成了三足鼎立的形势,而 Android 系统的市场占有率是最高的。Android 系统之所以能够在市场上占据着第一的位置,一来是因为它依托着谷歌的品德效应和技术实力,二来是因为它是开放的,任何人都可以得到它的源代码,并且能够自由地使用它。既然 Android 系统是开放的,作为一个移动平台开发人员来说,当然希望能够深入地去分析和研究它的源代码了,然而,Android 系统的源代码非常庞大,我们需要循序渐进地去学习。

工欲善其事,必先利其器。为了全面、深入地理解 Android 系统的源代码,在正式进入 Android 系统源代码的世界前,我们手头上需要准备好一些参考资料以及实验环境,此外,还需要了解 Android 系统的架构知识。

参考资料

Android 系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心。我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与 Android 系统相关的资料。

我们知道,Android 系统是基于 Linux 内核来开发的,在分析它在运行时库层的源代码时,我们会经常碰到诸如管道(pipe)、套接字(socket)和虚拟文件系统(VFS)等知识。此外,Android 系统还在 Linux 内核中增加了一些专用的驱动程序,例如用于日志系统的 Logger 驱动程序、用于进程间通信的 Binder 驱动程序和用于辅助内存管理的匿名共享内存 Ashmem 驱动程序。在分析这些 Android 专用驱动程序的时候,也会碰到 Linux 内核中与进程、内存管理相关的数据结构。因此,我们有必要掌握一些 Linux 内核的基础知识,下面就介绍四本典经的 Linux 内核书籍。

  1. Linux Kernel Development.
    这本书的作者是 Robert Love,目前最新的版本是第 3 版。这本书对 Linux 内核的设计和实现提供了一个总览视图,从概念上对 Linux 内核的各个子系统的设计目标和实现思路进行了清晰的描述,非常适合初学者阅读。如果从软件工程的角度来看,这本书就相当于是 Linux 内核的概要设计文档。

  2. Understanding the Linux Kernel.
    这本书的作者是 Daniel P. Bovet 和 Marco Cesati,目前最新的版本是第 3 版。这本书对 Linux 内核的实现提供了更多的细节,详细地描述了内核开发中用到的重要数据结构、算法以及编程技巧,非常适合中高级读者阅读。如果从软件工程的角度来看,这本书就相当于是 Linux 内核的详细设计文档。

  3. Linux Device Drivers.
    这本书的作者是 Jonathan Corbet, Alessandro Rubini 和 Greg Kroah-Hartman,目前最新的版本是第 3 版。这本书更加注重实际操作,它详细地讲解了 Linux 内核驱动程序的实现原理和实现方法,读者可以跟着它来实际地编写出自己的 Linux 驱动程序。阅读了这本书之后,对我们后续去分析 Android 的专用驱动程序是有非常大的帮助的。

  4. Linux 内核源代码情景分析
    这本书的作者是毛德操和胡希明,是中国人自己编写的一本经典的 Linux 内核书籍。这本书最大的特点是从使用情景出发,对 Linux 内核的源代码作了详细的分析,帮助读者把枯燥无味的源代码给理顺了。

掌握了 Linux 内核的基础知识之后,还不宜马上就去分析 Android 系统的源代码,因为这样做是漫无目的的,我们应该带着问题或者目标去分析 Android 系统的源代码。要把问题或者目标挖掘出来,最好的方法就莫过于是在 Android 平台上编写自己的应用程序了。通过编写应用程序,我们可以知道 Android 平台都提供了哪些功能,进而我们就会想去了解这些功能是怎么实现的,这样就可以达到带着问题或者目标去分析 Android 系统的源代码了。这里介绍两个 Android 应用程序开发教程的书籍:

  1. Professional Android 2 Application Development.
  2. Google Android SDK 开发范例大全.

这两本书都使用了大量的例子来说明如何使用 Android SDK 来开发 Android 应用程序。读者可以根据实际情况来练习一下,主要掌握 Android 应用程序四大组件(Activity、Service、Broadcast Receiver 和 Content Provider)的用法,因为 Android 系统的整个架构和实现就是为了向开发者提供这四大组件来实现各种各样的应用程序的。在学习的过程中,如果遇到其它问题,还可以参考官方文档,其网址为: http://developer.android.com/index.html

环境搭建

开发 Android 应用程序可以在两种环境下进行,一是在 Android SDK 环境下进行,一般是集成在 Eclipse 里面进行开发,二是在 Android 源代码工程环境下进行,在这种环境进行开发的好处是可以使用一些在 SDK 中不公开的接口。但是如果我们要修改 Android 系统的源代码,或者为 Android 系统增加新的功能接口,那么就只能在 Android 源代码工程环境下进行了。由于我们的目的是对 Android 系统源代码进行分析,因此,我们在开发 Android 应用程序时,也在 Android 源代码环境下进行。这样,我们就需要搭建一套 Android 源代码工程环境了。

目前,Android 源代码工程环境只能在 Linux 平台上使用,而 Linux 系统的发行版本比较多,这里我们推荐 Ubuntu 系统。Ubuntu 系统是免费的,而且非常易于使用,安装和更新应用程序也非常方便,它的官方下载地址为: http://www.ubuntu.com/

安装好 Ubuntu 系统之后,我们就可以在上面下载、编译和安装 Android 源代码了,具体方法和步骤可以参考下面这篇文章:在Ubuntu 上下载、编译和安装Android 最新源代码

Android 系统的源代码工程默认是不包含 Linux 内核源代码的,如果我们需要修改 Android 系统的内核或者在里面增加新的模块,那么就要把 Android 内核源代码一起下载、编译和安装了,具体方法和步骤可以参考下面这篇文章:在Ubuntu 上下载、编译和安装Android 最新内核源代码(Linux Kernel)

Android 源代码工程环境搭建好了之后,我们就可以在里面开发新的应用程序或者修改系统代码了。增加了新的应用程序或者修改了系统的代码之后,不需要重新编译整个源代码工程,只要单独编译有改动的模块就可以了,具体方法可以参考下面这篇文章:如何单独编译Android 源代码中的模块

对于已经开发好的应用程序或者系统功能,如果想把当作Demo 展示给客户来体验时,我们既可以在真机上面运行,也可以在模拟器(Android 源代码工程环境或者Android SDK 环境都集成了模拟器)上面运行。当我们手头上没有真机,而且我们又不想把整个Android 源代码工程环境或者Android SDK 环境带去展示我们的Demo 时,就可以考虑把模拟器这两个环境中独立出来了,具体方法可以参考下面这篇文章:制作可独立分发的Android 模拟器

系统架构

Android 系统是按层次、分模块来设计的。在我们着手对 Android 系统的源代码进行分析前,需要对 Android 系统的架构有一个总体的认识,这样我们就能够快速地知道哪些代码位于哪个层次上的哪个模块中,节省搜索代码的时间,把更多的精力投入在源代码的分析上去。

整个系统划分内核空间和用户空间两部分。内核空间包含了进程管理、内存管理以及设备驱动程序模块等,其中 Android 专用驱动 Binder、Logger 和 Ashmem 就是在内核空间实现的。用户空间包含了硬件抽象层(HAL)、外部库和运行时库层(External Libraries & Android Runtime)、应用程序框架层(Application Framework)和应用程序层(Applications)四个层次。我们应该如何去掌握这个层次结构呢?最好的方法就是从学习 Android 的硬件抽象层作为切入点了。

可能读者会觉得比较奇怪,为什么要把 Android 系统的硬件抽象层作为学习 Android 系统架构的切入点呢?这个层次因为涉及到硬件,看起来这是一个比较复杂和深奥的知识点。其实不然,Android 系统的硬件抽象层在实现和使用上,层次都是非常清晰的,它从上到下涵盖了 Android 系统的用户空间和内核空间。内核空间主要就是涉及到硬件驱动程序,而用户空间就涉及到了 Android 系统应用程序层、应用程序框架层和系统运行时库层的相关知识。因此,学习 Android 系统的硬件抽象层,可以使读者快速地认识整个 Android 系统,从而对 Android 系统得到一个感性的认识,为后面深入分析 Android 系统的源代码打下良好的基础。

Android 硬件抽象层的学习可以参考下面的一系列文章:

学会了编写基本的 Android 应用程序并且对 Android 系统的整体架构有一个大概的了解之后,我们就可以去分析 Android 系统的源代码了。

在分析 Android 源代码的过程中,我们经常进入到应用程序框架层去分析它的源代码,而在应用程序框架层中,有一部分代码是使用 C++ 来实现的,这时候就会经常碰到智能指针,因此,我们把 Android 系统中的智能指针也作为一个基础知识点来学习。相信使用过 C++ 语言来做开发的读者对智能指针不会感到陌生。用 C++ 来写代码最容易出错的地方就是指针了,一旦使用不当,轻则造成内存泄漏,重则造成系统崩溃,因此,系统为我们提供了智能指针,避免出现上述问题。

在 Android 系统中,提供了三种类型的智能指针,分别是轻量级指针、强指针和弱指针,它们都是基于对象引用计数技术来实现的。轻量级指针的计数技术比较简单,只要对象的引用计数值为 0,它就会被释放。强指针和弱指针的计数技术相对比较复杂,一个对象可以同时被强指针和弱指针引用,但是这个对象的生命周期一般只受强指针的控制,即当这个对象的强引用计数为 0 的时候,这个对象就被释放了,即使这时候这个对象的弱引用计数不为 0。引进强指针和弱指针这种复杂的引用计数技术是为了解决垃圾收集(Garbage Collection)问题而提出的。考虑这样的一个场景,系统中有两个对象 A 和 B,在对象 A 的内部引用了对象 B,而在对象 B 的内部也引用了对象 A。当两个对象 A 和 B 都不再使用时,垃圾收集系统会发现无法回收这两个对象的所占据的内存的,因为系统一次只能收集一个对象,而无论系统决定要收回对象 A 还是要收回对象 B 时,都会发现这个对象被其它的对象所引用,因而就都回收不了,这样就造成了内存泄漏。如果采用强指针和弱指针技术,这个问题就迎刃而解了,即 A 和 B 都用弱指针来引用对方。Android 智能指针的学习,可以参考下面这篇文章: Android 系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

掌握了本文所介绍的这些基础知识后,我们就可以正式开始分析 Android 系统的源代码了。

关于作者

罗升阳,先后就读于浙江大学(学士)、上海交通大学(硕士)计算机专业。现在供职于国内一家互联网公司,从事软件开发工作,专注于移动平台开发。


感谢崔康对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2011 年 12 月 14 日 00:0026464

评论

发布
暂无评论
发现更多内容

618你的系统顶住了么?系统发生重大灾难难道只能“删库跑路”?

夜来妖

给行动找个理由

Neco.W

行动派 决策

小师妹学JVM之:GC的垃圾回收算法

程序那些事

JVM 「Java 25周年」 小师妹 JIT GC

老大吩咐的可重入分布式锁,终于完美的实现了!!!

楼下小黑哥

Java redis 分布式锁

架构师训练营第二章课后作业

叮叮董董

为什么坐车会晕车呢

石云升

生活,随想 日常思考 晕车

架构师训练营第2周学习总结

Season

极客大学架构师训练营

第二次作业

朱月俊

ARTS打卡Week 04

teoking

ios LeetCode ARTS 打卡计划

用接口隔离原则优化 Cache 类的设计

朱月俊

架构师训练营-第二章-依赖倒置原则&接口隔离原则

而立

极客大学架构师训练营

数据库周刊28│开发者最喜爱的数据库是什么?阿里云脱口秀聊程序员转型;MySQL update误操作;PG流复制踩坑;PG异机归档;MySQL架构选型;Oracle技能表;Oracle文件损坏处理……

墨天轮

数据库

依赖倒置原则

李广富

做一个有原则的码农可好?

Dawn

极客大学架构师训练营

第二次作业总结

朱月俊

依赖倒置和案例

王锟

架构师训练营第2周作业

Season

极客大学架构师训练营

哪些框架是遵循依赖倒置原则的?

朱月俊

第二周作业

武鹏

什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?

朱月俊

这也太拧巴了吧?结局意想不到

非著名程序员

程序员 程序人生 提升认知

基本的面向对象原则(Basic OO principles)

旭东(Frank)

编程思维 极客大学架构师训练营

品软件架构原则模式之美

老姜

架构师训练营二期作业

老姜

千万不能让程序员给娃娃取名字

码农神说

程序员

产品视角看推荐算法

峰池

人工智能 算法 产品经理 推荐算法

架构师训练营 - 第二周架构师实现自己架构的主要手段

zcj

极客大学架构师训练营

架构师训练营第二周

小树林

一个包子铺看懂 I/O 模型演变

小眼睛聊技术

Java 程序员 架构 后端 nio

“麻烦”的处理流程

zhoo299

随笔杂谈

架构师训练营第二章总结

叮叮董董

边缘计算隔离技术的挑战与实践

边缘计算隔离技术的挑战与实践

Android系统源代码情景分析:基础知识-InfoQ