本来是发表在《程序员》杂志的,结果编辑整理成一篇书评,内容和深度都大幅缩水,今天把原文post出来,希望能抛砖引玉。
我正式接触Android的准确时间应该在2010年9月份。那段时间,老听到公司有人说Donut,CupCake、Eclair等非常奇怪的词(直到现在,我也不中意Android的版本命名),心中不禁很仰慕:竟然还有这么多我闻所未闻的东西。所以心里就特别好奇。不久,我就加入了Android的开发,第一个接触的大模块是Audio。一看代码,就发现有更多不懂的词了,什么Binder、AudioFlinger、sp、wp等等。当时,我记得买了韩超老师的《Android系统原理及开发要点详解》,使劲看,磕磕碰碰总算是入了门。
随着工作的深入,我发现自己对Android的学习和理解进入了一个比较尴尬的局面。仔细分析,发现它和我的工作内容有关。我的工作大部分情况下是维护已有Android系统,简单点说就是改bug。再改过大量Bug后,脑子里边已经把对Android的理解和Bug关联到一起去。比如,若考察我对Audio的了解,那么我能很快说出相关的bug以及修改情况。但可悲的是,我却不能说出整个Audio的工作原理。这不就是典型的只见树木不见森林么?这个结局对我(也相信对所有软件工程师)来说是不可接受的。有问题就需要改正(反正改了那么多Bug了),所以我下定决心要尽快把所掌握的知识点打通,搭建一个较为完整的Android知识框架。抱着这种心态,再来看Audio,就发现它所包含的内容是如此之丰富,涉及到sp/wp、Binder、AudioTrack/AudioRecord、AudioFlinger、AudioPolicyService等众多模块(以前改bug的时候,眼睛里看到的就是bug,完全没关注这些东西)。
于是乎,我就开始了Android研究之旅。很显然,前途是光明的,道路却一定要曲折。首先碰到的曲折之处就是由于研究工作只能在工作之余,下班之后穿插进行,所以思路经常被工作打断。例如,刚看到某段逻辑,这时候来一个任务需要尽快修改,这时就不得不中止研究。等再回来时,发现脑子里几乎没有任何之前研究的信息了。为了解决此问题,我采用了一种方法,即大家都知道的中断处理。怎么做呢?我把研究过程分得很细,每一小步都记录自己的想法,思路,并随时总结。当研究过程被工作打断后,只要去看打断前的思路轨迹,就能很快恢复中断前的现场,以保持思维的连续性。我用得工具是Wiz云笔记,所有笔记都同步到云端。所以,不论在家,公司,甚至任何一个只要能上网的地方,就能随处把思维连接起来了。图1是这2年来,我在Wiz上记录的笔记的截图:
图1 我的Wiz笔记
图1是我在Wiz上积累的笔记的一部分。左边是研究2.3 Framework的记录,基本上每个模块都有一篇笔记。右边是其中研究ActivityManagerService的学习笔记。
另外,Android中各个模块的研究方法也是我一直在琢磨的。对于Native Framework层来说,其主要关注数据流程,例如Audio、Surface系统等,对于这种模块来说,用Source Insight多跟踪几遍代码就能搞明白。但对于Java Framework来说,其关注点是管理、交互规则。例如ActivityManagerService内部有大段代码来处理Activity不同启动模式(如SingleTop、SingleInstance等)的情况。对于这种模块,我之前也采用Source insight加蛮看的方式,结果整整2周,毫无进展。因为分支太多,堆栈太深,大脑很难处理。
怎么办?当然是能亲自动手调试相关模块是最好的了。所以,我花了一天时间从网上找调试System_Process的方法。结果把Google的一个论坛翻了底朝天,才找到一篇帖子,不过它指向的确是Android官方网页上的一个链接http://source.android.com/source/using-eclipse.html(这里边有详细的调试方法。看来,还是要先好好研究下官方网页才是)。掌握调试方法后,我又犯难了:那时Android 4.0刚出来,是不是调试一定要拿真机呢?(没想过其实用模拟器调试可以)。手头只有一个HTC G7。忍下心,想方设法编译了一个Android原生系统烧上去[1](boot.image刷得是CM7,2.3版本的,而system.image用得是我自己编译的4.0系统)。由于缺乏相关的HAL库支持,这个系统勉强能跑起来,其实也就是一个模拟器(到4.1时,我就没再折腾了,直接上模拟器调试)。不过对Java Framework的学习来说,这就足够了。有了Eclipse这个强大的调试工具,后面的研究工作真的是如虎添翼,进展非常快。尽管如此,整个ActivityManagerService研究下来也花了将近1个月的时间。直到感觉在知识结构上没有欠缺的时候,我才开始动笔写。当然,写书其实是一个反思过程,它会促使我回头来看之前的结论是否正确。
深入理解Android这两本书出来后,我也在想一个问题,读者看完这两本书后该达到怎样的境界呢?我心中有两个目标:
q 能从“基于Android并高于Android”的角度来看待和分析Android。对于卷I的读者来说,他们可能是芯片厂商、底层厂商的工程师居多。对于这部分读者,以后转向其他平台的可能性非常大。所以,一定站在更高的角度来学习Android,而不应该局限在这个平台。
q 能初步具有大型复杂代码的分析能力。对于卷II的读者来说,他们更多可能是Java程序员。Java有很多优秀的开源框架,但大部分程序员不会去研究其中的细节。对他们来说,目前缺乏的是大型复杂代码的分析能力(当然,如果您能完整看完《Linux内核情景分析》一书,则不属于此范畴)。这个能力实际上是内功,需要踏踏实实,潜心钻下去才能修炼得到。
这就是深入理解 Android 书写背后的故事,这里也欢迎读者参与讨论。另外,这套书有一个详细的发展规划( http://blog.csdn.net/innost/article/details/7648869 ),也敬请大家积极参与。[1] 见笔者博客http://blog.csdn.net/innost/article/details/6977167