如何学习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系统的源代码了。


——————————————————————————————————————————————————————————————————————

以下是百度知道的回答:

我干了3年Android sdk开发,觉得到了瓶劲没法更进一步,于是花了一年多点时间,大概摸到点门径。根据前辈的经验,Android底层完全入门需要两年。

先说下我的入门过程:
第零步,下载源码,我下的4.2的,框架层源码10G,内核2G多,ctags给框架层建的标签文件都有600M,当时让我有点震撼,用的vim+ctags+cscope来阅读,还算不错,架构挺清晰的。

第一步,我找到了一本好书《Android的设计与实现 第一卷》它讲了Android框架层的启动,初始化,服务框架初始化,Binder,消息循环,PackageManagerService,ActivityManagerService。据作者说后面会出讲UI子系统的第二卷,拭目以待。其实这本书看了几十页我就发现需要第二步的知识,否则看不下去,于是跳去第二步。

第二步,学习Linux系统编程,在看《Android的设计与实现》的时候我发现,框架层的Native部分,全是Linux编程。为了掌握这部分知识,我花了4个月学习了《Linux系统编程手册》(TLPI)这本1000多页的书,我以前是搞WIndows文件系统这块的,所以C语言还比较熟,TLPI的习题很有意思,量也比较大,坚持下来还是收获很多。

第三步,花了4个月学习了一些Linux内核的知识,看了LKD,PLKA看了一半多。越学越没底,觉得不懂得越来越多,不过这个也正常,只有靠慢慢磨,估计以后要不断的磨这块。

第四步,回头看Android源码,这次一口气看完了《Android的设计与实现 第一卷》,终于对框架层有了谱。同时真的数次把我看晕,前面看Linux内核源码都没这么晕,不断在Java层和Native层之间跳有点磨脑浆。其中我又觉得Java的基础没有打太牢,回去补了一个月的《Core Java》第八版。但是这书没有涉及UI子系统,于是又看了《Android内核剖析》

第五步,《Android内核剖析》(这本书实际上是讲框架层的,作者也是个搞嵌入式的,所以他在写框架层的时候文笔不太好,很罗嗦,不过还是有很多看点,到他后来写做ROM,玩开发板时估计是说到了他的本行,一下子遛起来了看得出还是挺有水平的,这本书知识有点旧毕竟讲的是2.3很多代码已经过时,但是作者很多点子很有参考价值)这本书讲UI子系统和按键/触摸消息处理系统还是很有分量的,尤其13章View绘制那里,结合源码研究很有收获。而后面他讲编译框架和ROM相关的东西都是挺宝贵的资料。

第六步,为了再补一下其他诸如电源管理模块等子系统的知识看了,《深入理解android》系列,个人认为这个系列看起来有点不太舒服,不过作为补充印证还是比较有价值。

第七步,《Android系统源代码情景分析》,罗升阳的源码分析大作,比《Android的设计与实现》分析得更细致,但缺点是涉及到模块比较少,选用的源码也比《Android的设计与实现》更旧一点。看完书后需要去研究作者的博客,东西挺多的,一定让你满意。

第八步,买块开发板自己玩。这步我还没走到,原因是我觉得我还差点准备知识。可能要再几个月,到时准备入块6410或者树莓派。

最后,由于我11年以前都是搞Windows这块的,所以对Linux知识不是很了解,不得已看了这么些书,如果是一直做Linux的人,很多步骤估计可以省掉了。直接上源码才是正道。

我本身做着移动GIS开发的工作,学框架层全是因为兴趣,但招聘平台Android框架层开发人员还是蛮有竞争力的有不少定制ROM,智能电视的工作都处于人才难求状态,毕竟有一定的门槛,现在各种ios培训,让奔着钱干开发的人纷纷涌入,而ios只能干sdk开发的缺点就暴露出来了,一堆新手老手,菜鸟大牛全挤在SDK开发这块,我觉得不太妙。 反观Android这边,虽然入门菜鸟没有搞ios来钱,但是可持续性很好,从sdk-》框架》驱动》内核这样干下去。干着干着发现自己渐渐变成了Linux开发者/嵌入式开发者的人也不少,新人,老手,菜鸟大牛各居其位,层次性很好。

阅读更多

没有更多推荐了,返回首页