本书首次将android的内部工作机制整理成了文档,揭示了Android中各种组件的执行逻辑和工作流程。
本书通过实验而不是源码,将Android系统层层拆解,令读者深刻透彻地掌握Android系统的内部技术:以init进程为切入点详细阐述了Android的启动过程和关键服务;从Android作为资源协调者和服务提供者的角度,重点分析了servicemanager 和system_server 这两个进程。同时,作者比较了Linux与Android系统的区别,并对Android系统的安全性做了深入的阐述。
本书采用了大量的图表示例和实验,表达新颖清晰,让读者能直观地掌握Android 的技术精髓。
本书适合广大移动开发者及对Android系统感兴趣的人员阅读。
不需要源码也能彻底掌握Android技术内幕,全程实验直接指导,层层拆解!本书被美国中情局,国内部分手机厂商作为员工培训教材!张鸿洋、腾讯科恩吴石老师、小米MIUI汪文俊老师等一致好评!
推荐序一
Android是当今最主流的移动端操作系统,然而作为安全研究者要找到一本适合入门学习的书籍却并不容易。本人总结其原因有三:第一,Android操作系统更新周期较短,特别是近两年Android自4.4.X更新至7.1版,它的系统安全特性已经发生了翻天覆地的变化,许多Android书籍自开始撰写到完工就需要几年时间,如果是英文书籍还涉及翻译的时间,通常读者拿到书的时候,内容已经比较过时了。第二,由于Android系统的复杂性,对作者的技术要求比较高。作者不仅要熟悉其原生(Native)层,对其Java层等组件也需要有了解。市面上的很多Android书籍,很少能较好地覆盖每一个面向,或者是只有一个侧重点,这导致读者即便通读全书,也无法了解Android的全部。第三,很多书籍从Android源代码入手来讲解原理,虽有足够的深度,但略嫌乏味,会给读者一种纸上谈兵的感觉,给读者的阅读增添了困难,令他们很难全部读完并完全理解。
《最强Android书:架构大剖析》是我见过的Android书籍中,最适合安全研究人员阅读的一本。此书的作者Johnathan Levin和译者崔孝晨都是本人的朋友,相信与这两位打过交道的朋友都会发现,他们精力非常充沛,虽然已经从事安全研究十几年,但对新技术仍然充满了热情和好奇心。在面对面交流的时候,他们经常对着一个技术点侃侃而谈、乐此不疲。而作者Johnathan Levin更是在本书中引入“互联网思维”,为本书设立了网站http://newandroidbook.com,并不定期撰写文章,听取读者的反馈和建议,把Android最新的、读者最想了解的特性分析更新到本书中。以上特性,保证了本书与那些“拿到就过时”的Android书籍相比,具有明显的优势。
一本好书,光与时俱进、有技术深度还远远不够,如何把一个复杂的操作系统的内部机制和原理,合理有序、循序渐进地传授给读者,也是一个需要推敲的问题,而这就不仅仅是要求作者技术功底深厚那么简单了。Johnathan Levin多年从事技术培训工作,这些积累的培训经验确保了本书的易读性:细心的读者很快就能发现,本书的每一章节都相对独立,无论是顺序阅读或者跳着看都没有太大的问题;书中大量使用图表、图片来叙述,让读者更直观地掌握各个知识点,并且通过实验的方式加深对各个知识点的印象,充分掌握一些比较重要的概念。而译者崔孝晨同志更是在确保把原书的含义完整无误地传授给读者的同时,加入了许多中国元素,在表达上更为生动形象——这样的合作,无疑是中国读者的一大福音。
Android的安全防护机制是多维的,我的团队成员何淇丹、刘耕铭在Mobile Pwn2Own 2016中远程攻破搭载最新Android 7.1的Nexus 6p设备,从攻破所利用的漏洞来看,很明显,安全研究者需掌握Android浏览器、框架组件、内核等安全特性并找出Java层、Web相关、原生层甚至内核层的漏洞,并串联在一起才能对Android进行有效的远程攻击、突破沙盒,最终实现提权。本书对Android安全特性的分析也是一大亮点,很好地覆盖了目前针对Android的攻击面。相信阅读本书一定会对您的工作有所帮助。
陈良 科恩实验室高级研究员
2018年6月于上海
推荐序二
自2008年Google发布Android的第一版以来,时至今日,无论是在系统特性、用户规模还是生态规模上,它都取得了惊人的进展,获得了移动操作系统领域的绝对优势。Android是开源的,这对于任何想要一探究竟的人都提供了非常大的便利,但同时由于Android系统本身日趋复杂,对大家也是个很大的挑战—— 一不小心就会陷进代码的汪洋大海之中。
Jonathan Levin作为操作系统领域的专家,依赖自己深厚的技术功底和多年的研究,独辟蹊径地分别从高级用户和开发者的角度来探索Android系统。读者手上的这本书是从高级用户的角度开始Android的探索之旅的。这本书我首先接触的是英文版,现在非常高兴看到这本书的中文版面世,能让更多的读者受益。
本书特别适合高级用户(MIUI称这部分用户为发烧友)学习使用。目前不少手机用户对各种硬件拆机评测很熟悉,
这本书有如一个软件拆解,作者有如庖丁解牛一般,把运行在手机中的Android系统逐层拆解。在简要地介绍了Android的版本演化历史之后,作者先从分区和文件系统开始,详细介绍了各个分区的作用,各个分区上存储的内容和数据,还用实验详细演示了如何制作一个刷机包。在介绍了这些静态的软件组成之后,作者开始详细探索这些静态的内容是如何动态工作的。书中以关键的init进程作为切入点,详细阐述分析了Android的启动过程;接着分析了启动过程中的关键服务:原生服务和Android框架服务。操作系统有两个重要的角色:资源的协调者和服务的提供者。作者重点分析了servicemanager和system_server这两个进程,它们构成了Android系统所扮演的两个角色的基石。
对Android系统有一点了解的读者可能知道,Android是基于Linux内核的,那么Android和一个常用的Linux系统有何不同?作者接下来就从一个Linux用户的视角来观察和分析Android系统,剥去构筑在Linux内核之上的那层Android外衣,让一个熟悉Linux系统的人跃跃欲试:“我也能构建一个Android系统”。本书最后概要性地讲述了一些Android的安全机制,虽然只有短短的一章,但是非常清晰,尤其是对selinux的描述。从上述的脉络可以看出,作者动静结合,抽丝剥茧一般把运行在手机里的Android系统清晰地展示在大家眼前。
本书虽然是从高级用户的角度来探索Android系统的,但也很适合Android开发者,尤其是Android系统工程师学习。要想剖析一个系统,得先了解使用它。这本书有如一盏指路明灯,让我们在Android代码的汪洋大海之中始终明确前进的方向。略有遗憾的是这本书来得有点晚,使我们在学习Android系统的过程中走过一些弯路,不过今天的读者可以幸运地站在大师的肩膀上了!在小米MIUI,我们也打算使用其中的部分内容作为内部培训材料。如果您正好打开本书看到了这篇序,诚邀您一起开始我们的Android系统探索之旅,这将是一个妙趣横生的旅程。谢谢!
汪文俊 MIUI系统平台部总经理
2018年6月
译者序
市面上关于Android的书籍可谓汗牛充栋,我甚至都不敢把书名Android Internals按照惯例译为《深入理解Android系统》——重名的书太多了。那么为什么还要把这本书介绍给国内的读者呢?因为市面上绝大多数的Android书籍都是从程序员的视角展开的,入门的门槛相对比较高。尽管开发Android App的程序员们自然应该对Android系统有一个深入的理解,但这并不意味着其他人并不需要理解Android系统。比如,电子取证人员,他们需要对Android中的文件系统及数据存放位置有一个清晰的认识,以便从中提取相关数据;喜欢折腾的技术发烧友,root掉系统之后一般都喜欢自己修改一下系统,比如禁用一些开机启动项之类的。如果无须依赖额外的App,只需一个文本编辑器就能完成相关修改,甚至给系统换上自己的开机动画岂不是很酷……诸如此类。但这些人中只有很少的一部分接受过正规的编程训练,因此市面上大部分的书籍对他们来说难度就太大了。
本书的作者Jonathan Levin,也是畅销书Mac OS X and iOS Internals: To the Apple's Core(中文版为《深入解析Mac OS X & iOS操作系统》)一书的作者。按Jonathan自己的说法,Mac OS X and iOS Internals: To the Apple's Core一书的读者反馈中,反映最激烈的问题是:太技术化了!许多读者读起来感到头大!所以在这本后继的Android Internals中,他把不需要代码就能表达清晰以及与开发人员关系不太紧密的部分放在这一本书中,而把剩下的、与开发紧密相关的部分放在了另一本书中。这一点从本书英文版的副标题“Power User”就可以看出来。那么什么是“Power User”呢?如果一定要和传统的桌面系统的用户相对应,这个“Power User”就相当于系统管理员(administrator)的角色。相对于普通用户,他需要对系统有更加深入的理解,能对系统进行更加详细的配置,因而也被认为可以拥有较高的权限(比如root)——本书的部分实验确实需要拥有root权限,且第8章中也专用了一个小节讨论root这一主题。
有人问,既然是讲系统内部实现,不讲编程又是如何把它讲清楚的呢?答案是使用实验。本书的内容是根据作者多年讲课的讲义,整理、精选 而来,通过在ADB(Android调试桥)中执行各种命令的方式(相对于阅读代码),比较直观地向读者揭示Android内部的工作原理。效果如何呢?别看广告,看疗效。上次曝出的CIA Value7的相关内容显示,这本书已经被CIA私下盗版,用于CIA特工的内部培训了。而可怜的Jonathan Levin既不敢告CIA侵权,又不能告WikiLeaks……,只好在本书官网上提供了已经被泄密的2015年6月版的英文版的免费下载链接——与其去WikiLeaks下载,不如上官网下载。不过读者也不必沮丧,自我开始本书的翻译以来,几乎每个季度都会收到Jonathan Levin发来的大量更新——其中包括历次Android系统更新的新内容,以及书中已经发现的一部分错误的更新(包括一些我发现的错误:)),使得我也不得不多次将译稿做一些必要的返工,目前出版的中文译本是以2016年11月底的最新版本为准(更新至Android Marshmallow PR1版)的,您大可不必担心白花银子。
在本书的翻译过程中,我们力求将原文准确、清晰地翻译成中文。有模糊不清之处,我们尽量通过与作者沟通、阅读源码和实验的方式搞清楚。但各类缩写还是本着忠实原文的原则,沿用原文的写法。如在本书中,Android JellyBean版会被缩写成J版或JB版,Android Lollipop版会被缩写成L版,Android Marshmallow版会被缩写成M版等。
本书由上海公安学院的教师教官完成翻译,第1章由殷方老师翻译,第2章由王宏老师翻译,其余章节由我翻译,全书由我统一校对,并经本书作者Jonathan Levin及其国内合作培训公司的同志审校。
最后感谢电子工业出版社刘皎老师在本书翻译过程中给予我们的有力帮助,感谢腾讯公司科恩实验室吴石、陈良、赵泽光等老师给本书初稿提出的宝贵意见。
囿于译者水平有限,书中必然存在疏漏之处,敬请读者不吝指正。
崔孝晨
2018年6月
前言
一、概览
购买了本书的朋友,毫无疑问你已经意识到了Android的重要性。这个启动于2003年的操作系统,在被谷歌收购之后,现在已经成为谷歌最得力的产品。它迎头赶上了苹果公司的iOS操作系统(也有人说是很接近了),不仅取得了移动操作系统领域内的绝对优势(截至本书付印时,它的市场占有率已经达到了令人惊异的82%了),而且还渗透到了其他平台上,成为可穿戴设备、TV和嵌入式设备上的操作系统。
Android是开源的,而且是可以免费获得的,这也就意味着任何人都能获得它,并对它进行修改,使之能够运行在任何一种平台上——事实上,这也是它能够力压群雄,占据市场主流的原因。不过,令人吃惊的是,尽管已被广为接受,但是至今仍然没有一本书来完成探究其内部工作原理并将其文档化的任务。前几年有一本名叫《构建嵌入式Android系统:移植、扩展和定制》 的书,作者是Karim Yaghmour——这本书给出了大量关于该操作系统通用结构的细节信息,但是其着眼点在于如何创建和修改源码,使之能运行在各种新的平台上,而没能给出操作系统本身的结构。事实上,在此书“内部结构入门”一节中,Yaghmour声称“要想完全理解Android系统服务的内部结构,无异于蛇吞象”。
我认为这还算是一种保守的说法,这也就是为什么本内容需要由好几本书组成而不是只有一本的原因。第1本(也就是你现在正在读的这本书)主要是从高级用户或者管理员的角度讨论Android。在这一本中,我试图从各种不同的角度,如Android的设计、文件系统结构、启动顺序、原生服务再加上Linux基底以及Linux基底对操作的影响来讨论这一操作系统。这一切都不涉及代码,只是试图尽可能地给你一个大致的概念和鸟瞰图。从某种程度上说,本书可以算作Yaghmour那本著作的后续之作,Yaghmour的那本书本身也是极好的资料来源,我强烈建议你找一本来读。
本系列的第2本(将于不久后出版)将会对Android讨论得更深,而且会把视线转向Android框架服务(framework)的结构——这显然对开发者更有吸引力:通过使用Java层上各种丰富的框架,开发者可以拥有把输入设备、传感器、图形图像之类的东西抽象化的强大能力。当然这一抽象化的能力也并非是没有代价的——复杂性隐藏在“水面之下”,只是大多数开发者对此安之若素(更有甚者还满足于这一状态)罢了。不过知识是力量的源泉,深入熟悉各类框架(及其底层实现机制)对于任何想要进行底层开发或者在性能调优、支持更多的硬件、安全研究等方面有所建树的人士都是至关重要的。
Android是一个不断飞速更新的系统。在本书开始编写时,最新版的Android系统还是KitKat,然后(尽管中间有过几次跳票)最新版就变成Lollipop了。而且这一趋势还在不断加快——由于Lollipop版被发现有不少Bug,谷歌又宣布将要推出Android Marshmallow版。不过,截至本书付梓时,Lollipop版显示出了它稳定的一面——所以我也可以骄傲地说,这本书已经反映了最新版……好吧,是截至出版之日。幸运的是,借本书自媒体出版的东风,我可以不断地紧跟Android系统的更新而修订本书的内容,读者现在看到的这一版已经更新到Marshmallow Preview Release 1版(2015年6月)了 。
我还试图从我的上一本书Mac OS X and iOS Internals中吸取一点“经验教训”。我收到的读者对那本书的主要批评之一是:那本书太技术化了,充斥着大量源码,非开发人员身份的读者读起来实在是太累了。我个人的信条是“读一下源码吧,淡定些!”——因为源码不像自然语言,(几乎)是不会有歧义的,因此也是用来描述系统的正确方式。虽然我还是坚持我的想法不动摇,但在这本书中,我还是在不牺牲细节信息的前提下,尽可能多地改用图表的形式来表达意思。[我把这一做法也用在了Mac OS X and iOS Internals一书的第2版上(这一版将于2016年下半年出版)——这倒也不完全是因为我想通了,心甘情愿地这么做,还有一个重要因素也在促使我这么做,那就是在那本书里更加深入地探讨了Mac OS X和iOS系统更底层、更隐秘的部分——这些东西可是没有源码的……]。
本书也十分强调动手实践,我从我们的Android培训课程里抽取了一些动手练习,并把它们改编成了书中的实验。如果你想要对相关章节讨论的主题有深入了解的话,这些实验对你来说无疑是极为重要的。Android是UNIX(实际上是Linux)的一种衍生品,而学习UNIX的唯一正确方式是用我们的手指,而不是用我们的眼睛或耳朵。在这些实验里演示了Android命令行接口(CLI,command-line-interface)中的一些非常有用的命令,以及深入了解操作系统内部结构的技术。更进一步说,有些实验在不同的Android环境下会产生不同的输出结果——这也使它们非常值得你在自己的手机/平板电脑上亲手做一遍,以体验不同厂商或操作系统版本在架构和实现上的不同之处。
二、全书内容鸟瞰
本书的内容编排,既可以让你能按部就班地逐页阅读,也能让你随便翻开一页就能读下去。书中的每一章都是独立成章的,在你阅读本书的电子版时,文中所提及的相关主题都是以超链接的形式给出的——直接点击它,你就可以跳转到相关章节进一步阅读,但是对于纸质版的读者,我就只能给出相应的章节编号(引用书中的内容时)或者URL(引用其他资料时)了。我也会在相应的地方附上所引用的AOSP文件的路径(尽管为了节省空间,是以缩略的形式给出的),要不然本书的主要用途就变成“防身”了……
第1章介绍了Android操作系统:介绍了它各个不同版本的演化史(从Froyo版开始,这是你目前在市场上能找到的最老版本的Android系统了,一直到Lollipop版 )。同时,在这一章里(从较高的视角)也通过逐一比较Android软件栈中的各个层(layout),阐述了Android的体系架构以及它的Linux基础。紧接其后,这一章还介绍了Android的衍生产品——既包括谷歌自己的,也包括其他厂商的(比如亚马逊的FireOS)。最后,这一章将对Android未来发展方向的设想和思考作为整章的小结。
从第2章开始,我们开始深入探索各种技术细节——第2章的主题是Android的分区和文件系统。我们先讨论Android使用的分区架构(不幸的是,各家厂商远远没有对此达成一致),以及文件系统——EXT4和F2FS。然后,我们将探究文件系统中存放的内容——如果你想要知道某个特定的系统目录或文件中存放的是什么数据,这将是非常有用的。此外,本章还会涉及一些内置应用的数据存放目录,如果你对电子取证感兴趣,这些内容无疑也是非常重要的。在这一章中还会讨论Android受保护的文件系统(OBB和ASEC)——尽管在系统被root之后,这些保护措施就会失效。最后,我们还会阐述Linux伪文件系统(cgroupfs, debugfs, procfs, sysfs等)在系统中扮演的角色。
第3章是在前一章的基础上展开讨论的——因为涉及分区。它解释了在Android系统启动过程中,各个分区所起的作用。我们先会讨论Android的启动镜像(尽管有时会有些不正确地把它称为ROM),以及怎样把它刷到设备的各个启动分区里去。Android默认使用的Boot Loader也会予以阐述(本书官网上还有一篇从更加技术的角度开展讨论的进阶阅读文章),以及启动镜像的其他一些组件[内核(kernel)、设备树(device tree)和initramfs]也会被详细讨论。本章中的相关实验还演示了如何把这些组件从启动镜像中解出来,修改其中的内容,然后再把它们重新打包回去——制作一个你自己的刷机包(当然安装这种刷机包的前提是:在你的移动设备上Boot Loader已经解锁了)。此外,在这一章中还讨论了通过无线网络发送更新镜像进行(OTA)升级,以及设备备份、重置和关机的操作过程。
第4章专门讨论一个进程/init。这个进程和它在UNIX系统中的同名进程一样,是负责在用户态中启动系统的。我们会详细解释启动的过程,并解释/init.rc文件中使用的语法。/init的其他一些作用,比如维护系统属性和监视硬件改变(以ueventd进程的身份),也会详细地加以讨论。
在第5章中讨论的是原生服务,也就是列在/init.rc文件中的,由/init进程启动的Linux二进制可执行文件(与之相对应的是Dalvik级的框架服务,这些服务是以system_server进程中的线程的形式被加载起来的,我们会在第2本中讨论这些框架服务)。在这一章中逐个详细介绍了你可以在自己的移动设备上找到的每一个守护进程——说实话,还真不少。
在第6章中简略介绍了Android框架服务的大致架构,解释了servicemanager和system_server进程在其中所扮演的角色——这两个进程共同构成了其余所有构建在其上的Android框架服务的基石。Binder也是这一章里的重头戏,我们会简略地对它进行一番描述,但是大部分细节信息还是要留待第2本讨论补充。我希望这一解释足以让你能更深一步地理解Android进程间通信和远程过程调用的内部工作机制。
第7章以Linux的视角来看待Android,也就是通过/proc伪文件系统以及使用Linux系统中的工具,观察Android系统中的进程及应用。这一章还有一个“一箭双雕”的作用——你可以把这一章讨论的绝大多数工具,用在你自己的Linux系统原生代码的调试工作中。
作为本书的最后一章,第8章是专门用来讨论安全的。这一章在本书的官网上有预览版(只不过在预览版中的编号中,它是第21章——当时我曾经天真地认为可以在一本书中把所有的问题都讲清楚),在这一章里将逐一详细讨论Android的所有安全特性——既包括Linux层上的,也包括Dalvik虚拟机层上的。同时,在这一章中还有一个小节专门来讲述Android设备的root问题——既讨论了“被厂商认可的”在设备启动时root的方式,也讨论了那些通过安全漏洞root设备的方法。
三、本书使用的排版约定
本书采用如下排版约定:
以filename这种格式表示文件名。
命令、系统调用名称以及框架类名都是以command(1)、systemCall(2)以及classes这种格式表示的。命令和系统调用名称后面跟的数字是指:在使用Linux的man命令打开的手册中,该命令或系统调用所在的章节编号。
此外,本书还有许多插图、代码清单和输出结果。插图是由系统组件或消息传递流程组成的图片,相对于输出结果,代码清单中给出的一般是内容固定的文件中的内容,而输出结果中给出的则是一连串命令的执行结果——它通常是某个实验的一部分。我制作输出结果的目的是:显示各条命令的执行顺序及其用法,所以输出结果中一般都是带注释的。
请注意输出结果中的细节——用户名(上面这个输出结果中的user)(以及命令行提示符是$还是#)能够告诉你,这条命令是在shell中就能执行,还是必须要有root权限才能执行的。主机名(上面这个输出结果中的hostname)则可以告诉你这条命令是在哪台设备上执行的——如果它是generic,表示是在一台模拟器中;如果是flounder,表示是在一台Nexus 9(L)中;如果是其他移动设备的名称(s3、s4、kindle或Nexus 5之类的),则表示是在一台对应的移动设备中;如果它是Forge,则表示是在作者自己的Linux计算机上运行的。我尽量避免在书中出现大段的代码(至少在本书中是这样的),在迫不得已的情况下,我也尽量只给出最关键的代码,此外,我也会在代码中加上帮助你理解代码的注释。代码的字体颜色也调整为能够同时兼顾彩色(如果你读的是PDF版)和黑白(如果你阅读的是纸质版)两种打印方式的颜色。
四、最后……
本书绝对是个大工程,我像在大海里捞针那样把最重要的代码从Android源码里挑了出来。但即便是这样,肯定还有人想要亲自查看相关源码。所以,我在每次讨论中都会给出相关的源文件,并且是以超链接的方式给出的(纸质书的读者就只好抱歉了,我会把它们统一放在一个表格里供你们查阅)。有兴趣的读者也可以去谷歌的Android源码网站,或者去http://source.android.com/用git或者repo命令下载最新版的Android源码。
这本书是我“一个人的战争”——除了封面设计(封面设计是Dino Tsiopanos送给我的礼物,Dino不仅是个很棒的工程师,还是个很棒的画家)。书中的所有内容,包括文字、图片、排版和编辑都是我一个人完成的。幸亏我还可以向我的两位审校Moshe Kravchi和 Arie Haenel寻求帮助,我真的非常感谢你们二位!Nikolay Elenkov(那本棒极了的Android Security Internals: An In-Depth Guide to Android's Security Architecture 一书的作者)也对本书提出了宝贵的意见和建议。Aviv Greenberg在出版前的最后一段时间里以最快的速度通览了全书,给了我非常重要的评论。我还要感谢Eddie Cornejo,你不光挑出了很多错别字,还让我有底气说:我(在书中)对所有操作系统的评价都是公正的。最后,我还要感谢Nikola Veljkovic,感谢你帮我修正了书中的许多打字错误。
此外,我还要特别感谢Yoav Chernitz。事实上,我在所有书中都应该感谢你——因为正是在你的鼓励下,我才会走上写书这条道路。或许对于我来说,这一切都是不言自明的,但我还是要把这件事告诉本书的读者,补上在本书的第1版(更新至Android Marshmallow版之前的那一版)中,没有对你表示特别感谢的缺憾。出于同样的理由,我还要特别感谢Yobo,因为是你引领我走上了Android研究之路,是你告诉我Technologeeks有Linux to Android和Android Internals这两门课的培训需求——它们现在已经是最热门的两门课程了,而且也构成了这套书(共两本)的基础。另外,如果不是Ronnie Federbush,我也不会考虑像现在这样,尝试自媒体出版,而且本书的第2本(即将出版)和Mac OS X and iOS Internals第2版也将以这一形式出版。
这里还要特别说一句,我个人最诚挚的感谢要送给Amy,我俩在一起世界才完美,从我上一本书开始(实际上是在所有的事上)你一直给予我无限的支持和鼓励。这是我永远要唠叨,永远不会忘记的感谢!
本书是我用vim编辑器以符合HTML5的格式要求全手工输入的(对,我保证,我确实就是这么干的!不过这次也是够了,我想下次我再也不会这么干了),所有的图片全是用SVG(又让我幼小的心灵受到了一次严重的创伤!)或PowerPoint画的,这也就能够解释为什么这本书花了这么长的时间才面世。不过好消息是本书的第2本(大概比这一本厚一倍!)应该也会在不久后出版。在书中做索引也是一件极其令人痛苦的事,所以我决定:在更新内容时,就不再做索引了(你只要直接在PDF里搜索相关内容就行了)。如果你在书中发现了任何格式错误或者技术错误,也请体谅一下我这些辛苦的工作!不过对于技术错误,我提供专门的奖励——每发现一个,就会有一定的奖励进入你的腰包。
我还维护了本书的官方网站,在这个站点上还有更多的进阶阅读材料和一些专门定制开发的工具,网址是:http://NewAndroidBook.com/。本书的勘误表——包括错别字和错误修订(我希望不会有),也会放在这个网站上。
如果你想要在推特上找我,请关注我公司的官推@Technologeeks,那里经常会推送一些我的书的更新以及扩展阅读材料。Technologeeks公司也提供关于Android、OS X、iOS、Linux及其他操作系统的专业咨询和培训服务,所以我也建议你关注一下我公司的网站http://Technologeeks.com/。特别要说一句的是:在我公司提供的培训服务中,关于Android和OS X/iOS的培训都是基于我这两本书的。我公司在领英里还有一个Android Kernel Developers群——如果你有兴趣的话,也可以加入这个群,来打个招呼(或是提些问题)。
我衷心希望你能觉得这本书的内容既有意思,又吸引人(好吧,我想应该是在技术书籍中比较吸引人)。在本书的官网上我搭建了一个论坛,恭候您的批评和建议。
现在就让我们正式开始吧!