构建安卓操作系统的团队-全-
构建安卓操作系统的团队(全)
原文:
zh.annas-archive.org/md5/895376063ab192a4f49419e7eac3672b译者:飞龙
前言

2010 年 5 月中旬,我走进了 Google 园区的 44 号楼,开始了在 Android 团队的第一天工作。离我办公桌不远的地方,至少有六台机器在制作各种各样的美味且浓烈的咖啡。我对这种对咖啡因的关注感到惊讶,但这并没有持续太久。
团队正在完成一个版本的发布(1),同时并行开始下一个版本的工作(2)。这两者都非常困难、耗时且至关重要,因为我们试图让 Android 在当时拥挤的智能手机市场中占有一席之地。那时总有一种疯狂奔向目标的感觉,我们尽全力去实现它,却不知道能否达成。节奏是如此迅猛,但工作又是令人振奋的——这不仅仅是因为咖啡因。兴奋来自于加入一个团队,每个人都全心全意投入到一个明确的目标中,无论这需要付出多大的努力。
在 Android 上的工作与我职业生涯的起点截然不同。
我从明尼苏达州一家保守的老公司开始了我的职业生涯,那时的工作时间是朝九晚五。公司依赖于员工在这里待上一辈子,甚至更久,每年感恩节会给退休员工送一只免费火鸡。我已经准备好了;只需要每周工作四十个小时,慢慢晋升,直到我准备好退休和领取我的火鸡。
一年内,我就感到极度无聊,二年后我便离开了,去读研究生,重新锻炼自己的技能,转向我真正喜欢的领域:计算机图形编程。研究生毕业后,我来到了硅谷,那个充满技术机会的地方^(3)。我加入了 Sun Microsystems,并在接下来的几年中蓬勃发展...直到另一个有趣的工作吸引了我。
接下来的几年,我不断地从一家公司跳槽到另一家公司,随着不同的工作、技术和人员的变化,我的技术生活也在不断发生变化。我曾在 Sun 工作(几次不同的职位),Anyware Fast(由几位朋友创办的承包公司),DimensionX(一个早期的网络初创公司,被微软收购),Intel,Rendition(一个 3D 芯片初创公司,被美光收购),以及 Adobe 工作过。
我的父亲在美国海军服役 21 年后退休,他一直不习惯我频繁更换工作。他问:“那养老金怎么办?那工作保障呢?那家庭的稳定性呢?”
他没有看到的是,这就是硅谷的常态,也是现在高科技行业越来越普遍的现象。每一份工作我都在积累新的技能,这些技能为未来的职业前景和产品奠定了基础。正是这种态度和现实,适用于所有在科技公司之间流动的工程师;我们在构建自己未来将继续用来解决各种产品问题的技能。正是这些多样化的背景,为新项目提供了急需的技能,帮助解决未知的问题并提供创新的解决方案。
2010 年,另一个机会出现了。罗曼·盖伊(Romain Guy),一个我曾在 2005 年他作为实习生时一起工作过(并且共同编写过一本书^(4)) 的朋友,遇到了一个问题。他于 2007 年加入了 Android 团队,但因为太忙,没能编写他知道必需的动画系统。但他认识我,并且知道这是我喜欢的项目。经过几次面试和五个月的等待,我加入了 Android 的 UI 工具包团队,来到了位于山景城 Google 校园的 44 楼,并开始比以往任何时候都更加努力地工作。
我从创建新的动画系统开始,接着在我们艰苦完成即将发布的版本时,参与了低级性能和图形软件的工作。我继续在同一个团队工作了多年,编写图形、性能和用户界面代码,最终领导了该团队好几年。
在加入 Android 之前,我的大部分项目都非常有趣……但并不太显眼。如果我的家人问我做什么,我会告诉他们我编写了哪些软件。然后,我会用一种模糊的方式描述可能会使用我的软件的应用程序类型,因为现实是,他们永远看不到我代码的结果。这些软件并不是普通消费者在现实生活中会遇到的东西。
后来我加入了 Android 团队,并开始编写世界各地用户每天都会使用的软件^(5)。或者至少,如果 Android 能够生存下去的话,他们会使用。
挑战
我们并不知道它会完全失败还是会成功。当它成功时,我认为人们既惊讶又兴奋。
—埃文·米拉尔
Android 初期的团队成员拥有丰富的经验,并且有着非常强烈的意见。他们对自己正在构建的东西充满信心,但在达到初始的 1.0 版本时,他们面临着艰难的挑战。
团队的目标是创建 Android 操作系统(OS)。这包括从低级内核和硬件驱动程序到整体平台软件的一切内容。它还涉及为应用程序创建 API、帮助构建应用程序的工具、与平台捆绑的一些应用程序,以及后台服务,以便这些应用程序能够进行通信。哦,他们还希望能将这些都和一款新手机一起发布。
该软件将免费提供给制造商,用于构建他们自己的手机。这些合作伙伴将负责硬件的开发,而 Android 将提供软件支持。操作系统将帮助手机制造商,使他们可以专注于硬件产品,将日益复杂的软件问题交给 Android 处理。同时,Android 还通过创建一个统一的平台来帮助应用开发者,覆盖各种手机设备。开发者可以为所有这些设备编写一个版本的应用,而不需要为不同的设备编写不同版本。
Android 团队得到了 Google 的财力支持,能够访问到一批在大规模编写软件方面经验丰富的内部工程师,面对着快速增长的智能手机市场,以及一个致力于将产品做好的团队。怎么可能失败呢?回头看,Android 的成功似乎是理所当然的。
但在早期,团队所处的现实与现在大相径庭,Android 的生存状态也更加岌岌可危。
一方面,团队可能得到了 Google 的经济支持,但 Android 仅仅是 Google 投资的众多项目之一。Google 对 Android 的赌注并不是 Google 全力支持它,而是公司资助一个团队去探索它的潜力。^(6)
此外,Android 进入的是一个有着许多老牌竞争者且没有明显市场空白的新行业。在市场的低端,全球有众多诺基亚手机在销售。Danger、BlackBerry 和 Palm 都为他们忠实且热情的用户提供了有趣的智能手机(7)选项。还有各种微软手机可供选择。而且任何在软件行业工作过的人都知道,你总是应该对与微软竞争保持警惕。(8)
然后,2007 年苹果进入了市场,带来了另一个已经拥挤的竞争领域中的新对手。虽然苹果在手机领域是新手,但它们已经在操作系统、消费类计算设备以及热门的 iPod 上有了证明的成功记录。
在 Android 发布新闻稿,甚至是发布产品之前,所有这些参与者都已经在行业内建立了稳固的地位。
为了在这个竞争激烈的市场中尝试竞争,早期团队专注于以单一的目标推进 1.0 版本。每个人都专注于这个目标,大多数人在疯狂的紧迫期里不间断地工作。
但知道他们想要构建这个操作系统并不意味着每个人都同意如何构建它,或者它一定会成功,甚至不知道他们究竟在构建什么。团队中的工程师 Andy McFadden 说道:“我们有很多人对做事的对与错有强烈的看法。有时候他们意见不合,争论有时也会变得非常激烈。”
即使 Android 达到了 1.0 版本,第一个 Android 手机发货时,团队中的人们也没有明显感到这个项目会成功,甚至会继续进行下去。团队中的技术项目经理(TPM)Ryan Gibson 说道:“在那些早期的岁月里,Android 的氛围就像是一个不被看好的弱者,时刻面临失败的边缘,必须拼命努力才能取得一点进展。成功远不是必然的。我们落后了一年。如果我们再拖入下一年,可能就成了历史的脚注,而不是一个可行的替代方案。”
自从我加入团队以来,这些年里,我听到过 Android 早期开发的故事和困难,因为每个人都在努力将平台推进到能够竞争的位置。然后,在我在团队的期间,我看到了 Android 取得了一些成功,这就引出了一个问题:如何做到的?也就是说,Android 发展的哪些因素促成了它从那些初期不稳定的岁月到如今的惊人增长?
写这本书的想法源于我意识到,随着那些开发 Android 的人转向其他项目并忘记发生过什么,Android 的发展故事最终会被遗失。2017 年,我开始记录早期团队成员的对话,以捕捉这段故事。
实现细节^(10)
这本书很长(比我开始写作时预期的要长得多,尽管比我的第一稿要短得多,你们可以感谢我)。这里有几个阅读的小贴士,可以帮助你更清楚地理解这个庞大话题的组织结构。
首先,关于“Android”这个词的一点说明。让我编辑疯掉的事情之一,就是我经常使用“Android”这个词,意味着从创业公司,到它被谷歌收购后的团队,再到正在构建的软件平台,再到手机产品,再到开源代码,甚至是某个人的昵称。
这里的根本问题是…这正是 Android 团队使用这个词的方式:它可以指公司,可以指谷歌内部的一个部门,可以指软件,可以指手机,可以指生态系统,也可以指团队。
有一集瑞克与莫蒂^(11),不同星球的居民用“squanch”这个词以各种看似不相关的方式表达。最终,瑞克解释道:“Squanch 文化更…更依赖于上下文,而非字面意义。你只需说出你 squanch 中的内容,人们就能明白。”
Android 就是这样。你只需说出你 Android 中的内容,人们就能明白。
其次,故事是按时间顺序讲述的…大致如此。也就是说,我按照时间的流动顺序描述发生的事情以及做这些事情的人,因为时间是组织复杂互相关联事物的有力工具。然而,由于许多事情是并行发生的,所以实际上不可能严格按时间顺序讲述这个故事。所以,你会注意到,故事可能会跟随某人在 1.0 版本或之后的工作进展,然后时间线可能会倒回,讲述团队中另一个人的故事。
说到时间,这本书的故事从 Android 的成立开始,一直到 2009 年底。大部分内容发生在 1.0 版本发布之前的时期^(12),即 2008 年底。到 1.0 版本时,支撑 Android 未来发展的大多数基础都已经搭建完成。时间线再延伸到 2009 年底,那时在美国发布的摩托罗拉 Droid 手机让人们首次看到了 Android 未来成功的曙光。
最后,我希望这本书能被所有人阅读,而不仅仅是那些了解(并且,坦率地说,可能真的关心)技术细节的软件和硬件工程师。我尽力避免过于技术化的内容,以免在过程中丢失读者。但要描述一个操作系统是如何构建的,就必须使用像“操作系统”这样的术语,而这些术语对于那些没有写代码为生的人来说,可能会感到陌生。我会尽量在讲解时定义这些术语^(13),但是如果你在某个段落卡住了,不知道API是什么意思,或者我所说的CL指的是什么,可以查看附录中的“术语”部分。
就这样开始了
在 2017 年 8 月^(14),我开始与那支早期团队进行对话,首先是与 Dianne Hackborn 和 Romain Guy 的一次录音午餐聊天^(15)。从那时起,我继续采访(大多数是面对面,有时也通过电子邮件)早期团队中的大部分成员,整个过程持续了几年。
对于面对面的访谈(无论是现场还是通过视频聊天),我带了一个录音麦克风^(16),很快就意识到手写笔记是远远不够的。一方面,像 Dan Sandler 和 Dianne Hackborn 这样的人讲话速度比我思考的速度还快,更别提写字了。而且,录音还让我能够更多地参与讨论,而不是只顾着疯狂地做笔记。
我花了很多时间进行这些对话。然后,因为书面文字比音频录音更容易查阅和搜索,我花了更多的时间将对话转录成文字文件^(17)。在这个过程中,我花了很多高质量的时间去聆听、转录和阅读这些对话,我意识到一件美妙的事情:这些对话不仅仅是书籍的研究资料;它们就是这本书。我原本打算将访谈作为背景材料,帮助我理解大局、时间线和一些我原本无法发现的细节。但我没有预料到的是,每个人都将如何用他们自己的话讲述这个故事。
在这本书中,我引用了很多来自这些访谈的内容。事实上,我尽量用引用而不是自己的描述,因为从那些亲身经历的人视角讲述故事,能最真实地反映他们各自的声音和对事件的独特看法。
请跟随我一起踏上这段探索安卓核心的旅程,了解团队和操作系统是如何诞生的,通过那些促成这一切的人们的声音。
第一章:Android。。。相机操作系统?

数码相机的 Wi-Fi 接口在一些高端单反相机中开始出现。这些设备越来越强大,但用户界面(UI)非常糟糕。
—布莱恩·斯威特兰
一开始,Android 正在开发一个名为 FotoFarm 的数码相机平台。
2003 年的数码相机技术变得越来越有趣;数码单反相机(DSLR)结合了高质量的镜头和越来越大的传感器,能够在数码图像文件中捕捉更多的细节。但这些相机的软件……并不太好。
安迪·鲁宾曾创办并刚刚离开了手机制造商 Danger,他在寻找新的项目。与前 WebTV 同事克里斯·怀特一起,他们成立了一家公司,目标是制作更好的相机软件。安迪担任 CEO,克里斯担任 CTO,他们在 2003 年底创立了 FotoFarm,为数码相机提供操作系统。他们设想的软件将提供更好的用户界面和网络功能,还能运行应用程序。结合更强大的相机硬件,他们将推动摄影和成像功能与体验的极限。
克里斯告诉安迪,他认为他们能想到一个比“FotoFarm”更好的名字。安迪已经有了网址 android.com,于是他们将名字改为 Android,并聘请了设计公司 Character 来帮助创建公司的品牌形象,包括他们的 logo 和名片。
他们所需要的只是让投资者相信他们的 Android 相机平台的愿景。但其他人并不关心相机,大家都只想谈论手机。
安迪邀请尼克·西尔斯到 Android 位于帕洛阿尔托的办公室,向他推销相机操作系统。两人曾在 Danger 的 T-Mobile Sidekick 手机项目中紧密合作过。尼克决定离开 T-Mobile,但仍希望继续从事手机领域的工作。他想打造一款比他们在 Danger 所做的更先进的消费类智能手机。尼克认为,Danger 未能达到预期成功的原因之一,是设备本身的界面和形态设计。“每个人都把它看作是一款标志性设备,但我们知道它的形态设计还不够小,无法让人们想要随身携带。它仍然是一款厚重的设备,屏幕也是一个独立的部分。”
Android 的愿景并没有吸引尼克,他对相机不感兴趣。手机才是他经验和兴趣的所在。他告诉安迪,“如果你改变主意,做手机的话,给我打个电话。”
在那次谈话后不久,安迪与另一位来自 Danger 时期的同事里奇·迈纳进行了交谈。里奇代表他的雇主——移动运营商 Orange,成为 Danger 的早期投资者。通过与安迪的合作,里奇了解了他,并一直保持联系,想看看他将来会做什么。
Rich 和 Nick 一样,建议安迪的初创公司应该考虑制造手机,而不是相机。Rich 在手机市场有着悠久的历史,他看到了 Android 在该领域改变局势的机会。Chris 也在和 Andy 讨论这个可能性。但 Andy 仍然心存抗拒。
安迪不想再做手机了。他最终对在 Danger 的经历感到失望,因为那并没有按照他预期的方式发展。但与此同时,他向风险投资家(VCs)推销相机的想法,却没有得到任何兴趣。而且,他也看到了相机市场的现实,当时的销量开始下滑,因为制造商们开始将相机集成到手机中。
2004 年 11 月,安迪又一次与风险投资家开会。他推销相机操作系统时依然没有引起兴趣。所以他提到了手机作为一个可能性,结果房间里的人开始关注起来。
安迪放弃了。他重新联系了 Nick 和 Rich,并告诉他们,他现在准备做一个手机操作系统了。
这正是 Rich 和 Nick 所需要的。他们开始与 Andy 一起合作,制定关于手机操作系统的商业计划和推介资料。在 2005 年初,他们作为共同创始人加入了 Android。
安迪没有建成自己的相机操作系统。但鉴于今天手机上相机的重要性,你可以说他创造了史上最广泛使用的相机操作系统;他只是通过间接的方式做到了这一点。
第二章:农场团队

这就是 Android 最酷的部分之一:在最初的一百人中,几乎每个人之前都做过类似的事情。我在做那些我已经犯过错误并从中吸取教训的事情。每个人都是如此。
—Joe Onorato
和几乎所有其他技术产品一样,Android 的成功不仅仅是产品和发布的结果,更在于那些构建它的人以及他们在塑造过程中所带来的集体经验。所以,Android(这个手机操作系统)是如何诞生的故事,早在这家创业公司成立之前,就已经开始了,源自团队成员们的集体历史。
Android 的诞生是因为许多其他努力先行发生了。或者更确切地说,Android 的存在源于那些构建它的人,之前曾在多个其他公司一起工作,这些公司在移动平台和桌面平台之间不断变化的 Venn 图中互有交集。正是在这些公司中,早期的 Android 开创者们积累了他们的知识、技能和与同行的协作经验。当他们加入 Android 团队时,他们能够迅速上手,并在相对较短的时间内从零开始构建一个全新的操作系统。
对早期 Android 团队影响最大的一些公司包括 Be/PalmSource,^(1) WebTV/Microsoft 和 Danger。虽然这些公司没有直接为 Android 提供支持,并且大多数未能在市场上产生大的影响,但它们都提供了一个肥沃的试验场,工程师们在这里学到了重要的技能,这些技能在他们后续开发 Android 操作系统时得到了充分应用。
Be 公司
Be 操作系统(BeOS)如今只不过是计算机历史中的一个脚注^(2)。事实上,你甚至可能从未听说过 Be 或 BeOS,更不用说使用过这家公司的软件或硬件了。但 Be 对计算平台的影响是巨大的,至少有一个原因就是它集结了大量后来组成 Android 团队的员工、热衷用户和开发者。^(3)
Be 是在桌面计算机战争的后期加入的,出现在 1990 年代初期,推出了一款新操作系统,试图与已占据市场的微软和苹果桌面系统竞争。但它的表现并不理想。
Be 在发展的过程中尝试了许多不同的方向。他们出售了自己的计算机硬件(BeBox)。他们将 BeOS 移植到 PC 和 Mac 硬件上,并尝试销售操作系统。他们差点被苹果收购(事实上,苹果给了他们一个收购报价,但当 Be 的 CEO 利用拖延时间作为谈判策略时,史蒂夫·乔布斯突然介入,成功说服苹果收购他的公司 NeXT Computer)。1999 年,他们进行了一次不太成功的首次公开募股(IPO)。^(4) 然后在 2000 年,当没有人购买 Be 的硬件和操作系统时,这家公司尝试了他们称之为“聚焦转变”的举措,开发了一个为互联网设备设计的操作系统,但人们还是没有购买。

Macworld曾刊登过一篇关于苹果收购 Be 的故事,然而在苹果收购 NeXT Computer 后,这笔交易没有成行。(图片由 Steve Horowitz 提供。)
最终,在 2001 年,Be 被 Palm 收购(当时 Palm 将该部门拆分成一个新公司,名为 PalmSource),以为未来的 Palm 设备构建操作系统。具体来说,Palm 收购了 Be 的知识产权(IP),并聘用了许多 Be 的员工;Palm 并未收购该公司、债务或资产(如办公家具)。^(5)
Be 在 Android 历史上具有重要意义,原因有几个。首先,Be 吸引了许多对操作系统开发各个方面感兴趣的工程师,从用户界面、图形、设备驱动程序(让系统与硬件(如打印机和显示器)进行交互)到内核(处理平台基础设施重任的低级系统软件)。从事这些项目培养了构建像 Android 这样的操作系统所需的技能。
此外,BeOS 成为了操作系统中的经典之作。世界各地的工程师们在大学或个人项目中接触到 Be,并对其进行实验。Be 在多媒体(6)、多处理(7)和多线程^(8)方面的先进能力使其成为了操作系统开发爱好者的有趣乐园。许多在 Android 团队工作的工程师虽然没有真正加入过 Be,但他们在个人时间里曾经玩过 BeOS,并对操作系统开发产生了热情,这种热情后来被带入了 Android 团队。
当 Be 被收购时,一半的工程师去了 Palm 工作(很快进入 PalmSource)。^(9) 在那里,他们继续从事操作系统的开发,构建 Palm OS Cobalt,尽管最终没有在任何设备上发布。在此过程中,工程团队继续磨砺操作系统开发技能,同时也积累了在移动设备上的经验,这些设备正是他们 Palm OS 工作的目标。

加入 Palm 的 Be 工程师们制作了印有他们对收购的讽刺看法的 T 恤。(图片由 Mathias Agopian 提供。)
PalmSource 在 2005 年底被 ACCESS 收购。由于对新公司发展方向缺乏热情,许多前 Be 的工程师最终加入了谷歌的 Android 项目。到 2006 年中,前 Be 员工占据了 Android 团队的三分之一。
WebTV/微软
WebTV 成立于 1995 年中期,并在不到两年后的 1997 年 4 月被微软收购。^(10) 那些在 Android 早期加入的微软员工,特别来自于最初成立 WebTV 团队的人,以及其他电视/互联网团队(如 IPTV),他们都属于同一部门。
WebTV 提供了第一个将互联网带到电视机上的系统之一。今天看来,这似乎有些可笑,因为我们中的许多人通过电视上的互联网服务消费几乎所有电视内容。但在当时,这些是完全不同的世界,大多数人访问互联网的方式是通过个人电脑。
WebTV 团队正在创建一个供用户消费内容的平台,这些内容不仅限于电视节目,因此他们需要开发在硬件上运行的软件平台、用于构建应用的用户界面层,以及该平台的应用程序。团队开发了一个操作系统,一个 UI 工具包(负责在应用程序中进行用户交互的系统),一个编程层(用于编写应用程序),以及适用于互联网设备的应用程序。所有这些努力都积累了实践经验,这些经验对后来加入 Android 团队并构建类似东西的人来说非常有用。
Danger 公司
Danger 公司成立于 1999 年 12 月,由 Andy Rubin、Matt Hershenson 和 Joe Britt 创办。最初,公司正在开发一款便携的数据交换设备,昵称为“Nutter Butter”^(11),因为它的外形像这种名字的饼干。

Danger 的 Nutter Butter 设备。它是用来交换数据的,而不是用来当零食吃的。(图片由 Nick Sears 提供。)
在 2000 年至 2001 年点 com 泡沫破裂期间,公司转向开发一种能够自动无线同步数据的设备。但那还不是一部手机。还不是。然后,在 2001 年 1 月,Andy 在 CES 上与 T-Mobile 的 Nick Sears 会面。^(12)
Nick Sears 与移动数据
1984 年,Nick 在美国陆军服役,从事行政工作以赚取大学福利。然后,他在超级碗期间观看了苹果公司传奇的 1984 年广告。“我知道我们正处在技术革命的起点。我走进 ComputerLand,花了 3200 美元,买了一台 IBM PC(一个软盘驱动器),DOS,Turbo Pascal,Lotus Notes,WordStar 和一个点阵打印机。白天,我是每分钟 40 个字的打字机。晚上,我成了一个温和的计算机迷。”
Nick 将自己的计算机技能与商业学位相结合,并在 80 年代末加入了 McCaw Communications。在 McCaw 公司内部,他见证了移动行业和互联网的成长,持续了十年。到了 2000 年,他加入了 T-Mobile,^(13)成为公司负责无线数据战略的副总裁。
T-Mobile 最近专门组建了一个团队,致力于无线互联网的发展。它们是美国唯一拥有 GPRS^(14)技术的运营商,而且它们的数据网络在其他运营商之前大约一年就准备好了。Nick 的任务就是实现这一目标。这意味着要出去寻找,或者必要时创造,能够利用这个新数据网络的设备。
Nick 和他的团队意识到,如果没有更好的键盘体验,丰富的互联网体验将无法实现。在当时的手机上,仅使用传统的 12 键拨号盘进行任何有趣的网上操作既不可行也不愉快^(15)。因此,团队专门寻找带有 QWERTY 键盘的潜在设备^(16)。
T-Mobile 当时已经与 RIM^(17)合作,并说服他们为之前仅限数据的黑莓设备加入手机功能。但是,那些设备的外形设计(尤其是深受用户喜爱的腰带夹)不会吸引消费者,因为他们更倾向于寻找一些不那么以商业为中心的设备。
Nick 于 2001 年参加了 CES,寻找消费类设备的可能性。他与 Danger 的 CEO 安迪·鲁宾会面,安迪向他展示了 Danger 设备的最新版本的模型。像黑莓一样,它也是仅限数据的。和黑莓一样,Nick 告诉安迪,T-Mobile 需要将其做成手机,于是 Danger 开始调整,加入了手机功能,并与 T-Mobile 合作推出了第一款设备。
Nick 回忆起 T-Mobile 推动这些新型数据启用手机的过程时说:“我们是第一个将手机带入智能手机时代的人。”
2002 年 10 月,Danger 推出了他们的Hiptop^(18)手机……但 T-Mobile 坚持要更改名称。正如 Nick 所解释的:“商务高管和工程师像佩戴 HP 计算器一样把黑莓设备挂在腰间,我们认为消费者不会用手机这样做。”于是,这款设备以 T-Mobile Sidekick 的名称发布。
这款设备占据了当时功能手机和未来智能手机之间的一个中间地带。例如,Hiptop 提供了一个真正的网页浏览器(相比于当时手机上普遍使用的非常有限的移动浏览器)。此外,Danger 手机还拥有一个应用商店,这是同类产品中的先驱之一。但该商店由 T-Mobile 进行策划;当时运营商控制着能够在其网络上运行的应用程序,这被称为围墙花园^(19)。
这些功能,加上云/网络能力,包括 Hiptop 的持久连接,能够即时更新电子邮件和聊天信息,再加上空中更新,后来在安卓系统上也得以体现,一些开发者也曾在 Danger 手机上让这些功能得以实现。
最终,Danger 手机未能从小众市场突破到大众市场的成功。互联网电子邮件、消息传递和浏览的结合,加上 T-Mobile 激进的无限数据定价,创造了一款在当时具有强大功能的手机。Danger 设备吸引了很多关注,尤其是在科技^(20)和流行文化圈子中(包括 2006 年电影《穿普拉达的女王》中的第二款 Hiptop 设备)。但这些手机未能赢得消费者的心和钱包。尽管如此,这些设备在推动移动领域发展方面起到了重要作用,从创造出的技术,到这些设备所带来的新体验,再到 Danger 在此过程中培养出的工程师团队。
一起努力
早期大部分安卓团队成员曾在以下一家公司或多家公司工作过:Be/PalmSource、WebTV/Microsoft 和 Danger。直到 2006 年中期,这些人占团队的至少 70%,并且一直是团队的多数,直到 2007 年。

到 2006 年为止,加入安卓团队的大多数人曾在以下一家公司或多家公司工作过:Be/PalmSource、WebTV/Microsoft 和 Danger。
在科技界,尤其是硅谷,这一直是一个事实:人们在公司之间流动,并在职业生涯中不断在不同的地方和背景下共同工作。当你离开公司时,永远不应该断绝关系。首先,待人得体本就是正确的做法。但在硅谷,断绝关系是一个非常糟糕的主意,因为很有可能你未来的某个时刻会需要与那些同样的人再次合作;如果当时这些桥梁没有被焚毁,那将是非常方便的。^(21)
在安卓的案例中,这远远超出了人们最终进入同一家公司这一间接且偶然的效果。早期团队在很大程度上依赖他们之前的公司经验,并招募了那些(a)他们已经有工作关系的人,以及(b)那些有着安卓所需的工作经验的人:操作系统、嵌入式设备和开发者平台。
通过早期加入安卓,这些人启动了一个紧密合作的团队,大家都知道自己在做什么,这使得他们能够比预期更快地构建这个新操作系统。
2007 年加入安卓团队负责工具开发的 Xavier Ducrohet 观察到:“那些最早加入的人来自其他地方——很少有来自谷歌的。那些已经发布过操作系统的人。能做到这一点的人有多少?他们发布过小型操作系统,并从他们的错误中吸取了教训。”
Dan Egnor 也于 2007 年加入,负责开发空中更新系统,他注意到团队中已经在的成员之间的动态。“有一种强烈的感觉,通过共同的历史,大家彼此了解,他们知道彼此的不满点,尊重的方面,哪些人可以信任完成任务,他们有清晰的责任领域。即使只有几个月的时间,大家也能流畅地提起对方的名字。人们有强烈的感觉,知道别人做了什么,以及如何做的。”
这些公司或它们的产品并非都成功,但在它们的建设过程中获得的知识极大地促进了 Android 团队后来建立一个可行平台的能力。Steve Horowitz 曾在 Be 和微软的 WebTV 团队工作,后来管理 Android 工程团队,他说:“这就是这个世界的一部分:你从失败中学到的可能比从成功中学到的更多。”
Dianne Hackborn 曾在 Be 和 PalmSource 工作,加入早期 Android 团队之前,她说:“我们大多数人在加入 Android 团队之前,都经历过不少失败,其中可能是时机、情况或其他原因没有促成成功。我算过,我在 Android 之前参与过三到四个失败的平台。但我们一直在尝试,从每次失败中吸取教训,并将从中获得的知识运用到 Android 的工作中。”

Android 在成立之前已经有了悠久的历史,这建立在所有为其早期团队做出贡献的公司历史之上。
第三章:扩展团队

到了 2004 年底,这家小型 Android 初创公司需要增加人手。Andy 和 Chris 提供了足够的工程和设计支持,使得一些初步的愿景和技术得以实现。但当他们开始向投资者推销实际产品时,他们需要一个工程团队来帮助创建平台和技术演示,而创始人则专注于业务发展。
与此同时,曾在 Danger 与 Andy 共事的 Brian Swetland,正在寻找新的挑战。
Brian Swetland,Android 的首位工程师
从五岁开始,Brian Swetland(团队中简单称为“Swetland”)就成为了一名系统程序员。
“我父亲在我们的厨房桌子上用两三晚的时间焊接了一台 Timex Sinclair 克隆机,这是一台带膜键盘的单板计算机,并将它接入了一台破旧的黑白电视。你可以用 BASIC 输入指令。它能做一些事情——它就像一个神奇的东西。你会学到一些人生课程,比如永远不要拿起烙铁的那一端。”
Swetland 从小就一直在编程,直到大学时,虽然没有完成他的计算机工程学位。“大二那年,我有一段时间没去上课。因为本地 ACM 分会的项目、在 NCSA SDG 的工作以及参与开发 X/Mosaic 网页浏览器让我分心。然后临近期末考试,一切变得不太好。”但正是因为编程爱好,他与 Be 公司建立了联系,并在尝试让 BeOS 在自己 PC 上运行时引起了公司的兴趣。
当 Be 发布了适用于 PC 的操作系统版本时,Swetland 将 CD 安装到了他的计算机上。但它并没有完全正常工作。“它没有识别我的硬盘,因为我的 PC 里只有 SCSI^(1)硬盘。所以我找到了我拥有的 BusLogic SCSI 控制器的手册,并想,‘这看起来并不复杂。’于是我给他们的工程师之一 Dominic Giampaolo 发了封电子邮件,他在 Usenet 上很活跃。”^(2) Dominic 给 Swetland 发了一份 BeBox 硬件的 SCSI 驱动程序示例。
“那个周末,我最终做出了一个适用于我拥有的 BusLogic 控制器的 SCSI 驱动程序。我成功启动了它,但有个问题;磁盘大小显示不正确。所以我回邮件告诉他,‘我写了驱动程序,但大小不对:我认为中间层有个字节序^(3)的 BUG。’
“他十五分钟后回了邮件,问我是否想要一份工作。”在一次前往加州的旅行和在公司的一整天面试之后,包括与 Dominic 进行的现场调试,Brian 收到了工作邀请。他回到家后,收拾好行李,两周后搬到了加州。他上大学的目标是最终编写操作系统。现在有机会立即开始,他认为大学学位可以等一等。
两年后,2000 年 5 月,Swetland 离开 Be 加入了 Danger,和前 Be(未来的 Android)同事 Hiroshi Lockheimer 一起工作。在 Danger,Swetland 负责内核和其他系统软件,并帮助推出了前几款 Hiptop 设备。但在最初几年后,大部分工作变成了增量式改进,或者是根据运营商要求实现的功能(或代表运营商取消的功能;有时甚至是根据产品经理认为运营商可能要求的功能而取消的)。Eric Fischer,曾在 Danger(后来是 Android)从事文本和其他平台功能开发的工程师表示:“我们在那里做的每一件事,都在运营商接受流程缓慢保守的阴影下,这个流程能够否决任何功能或设计。”
Swetland 总是对构建新系统比改进现有系统更感兴趣,他开始感到沮丧。到 2004 年,Danger 已经发展成了一个约 150 人的大公司,远非他在 2000 年加入时的小团队。而且已经有四年时间,他在这段期间不断加班,最初帮助 Danger 作为一个挣扎中的初创公司,然后帮助公司推出了前两款手机。所以在 2004 年 9 月,他休息了三个月来恢复因过度劳累和沮丧而产生的疲惫。
Swetland 并不打算离开 Danger,他只是需要休息。在休假几周后,他意识到自己不在工作岗位上也挺开心的。他还意识到,如果继续不回去工作,他也会一直很开心。更具体地说,他意识到他真的不想回去 Danger 工作。
但他还是需要一份工作。Be 和 Danger 曾是不错的软件工作,但并没有像每个人想象的那样带来丰厚的回报。^(4)
在 Danger,Swetland 和 Andy 相识较深,因为他加入时公司只有少数几名员工。所以当他开始寻找新机会时,他联系了 Andy。毕竟,Andy 曾创办过一家有趣的公司,也许他还会有更多的创意。果然,Andy 确实有;他与 Chris White 共同创立了 Android,并且他们正在寻找第一位员工。
那时,2004 年秋季,这家初创公司专注于开发一个开源的相机操作系统。Andy 向 Swetland 介绍了这个相机操作系统的想法,Swetland 对此产生了兴趣。如果说有什么吸引人的地方,那就是能够再次参与到一个新的操作系统的开发中,而这正是他所热爱的。而且至少这不再是手机;在他在 Danger 工作期间,他已经对这个动荡的领域感到厌倦了。所以他答应了,计划在休假结束后加入。
在 Swetland 加入之前,Andy 与 Nick、Rich、Chris 以及风险投资人进行了讨论,并决定改变 Android 的产品方向。
2004 年 12 月初,Swetland 在 Android 的第一天来到办公室,兴奋地开始做一些不是手机的工作。Andy 问:“如果我们在做手机,你会怎么想?”
Swetland 和另一个长期 Android 成员 Tracey Cole 一起加入了公司。Tracey 被聘为 Android 的首位行政助理,并在这一角色上工作了多年,一直是 Andy 的个人行政助理。5 Tracey 和 Brian 是第三和第四个加入 Android 的人,也是前两位非创始人员工。
Andy McFadden 与演示
2005 年 5 月,Andy McFadden(团队称他为“Fadden”6)加入了公司。Fadden 曾在 WebTV 与 Andy Rubin 和 Chris White 合作过。当 Andy [Rubin] 想要为他的初创公司招聘其他人时,他给 Fadden 发了封邮件:
WTF?
How are you?
I want to hire you. It's going to be huge™
13 岁时,Fadden 就在 Apple II 上编程 BASIC 和汇编 7。所以后来他成为了 Android 团队中负责 Android Dalvik 运行时低级代码的成员之一也就不足为奇了。“一些人(后来当 Android 在 Google 成为一个大团队时)不喜欢 Dalvik 虚拟机的部分代码是用 ARM 汇编 9 写的。当你从八年级就开始在计算机内部摸爬滚打时,你的视角就会不一样。”
安迪请来 Fadden 来帮助。10 当 Fadden 加入时,Android 的“产品”不过是 3,000 行 JavaScript,11 用各种开源库连接在一起。那时它还不是一个平台,而是一个用来帮助可视化一个并不存在的体验的原型。Fadden 的工作是将 Swetland 和 Chris 一直在做的这个概念演示转化为实际的功能,包括应用程序。创业公司必须能够向潜在投资者展示真实用户如何使用这个未来系统。
2005 年春季,Android 团队还没有产品,但他们对未来产品的愿景已经很明确。很多初创公司以更低的价格被收购了。
Ficus Kirkpatrick,初创公司的最后一位员工
在 Android 被 Google 收购之前,最后一位加入 Android 团队的人是 Ficus Kirkpatrick。
Ficus 从小就开始编程。真的很小。“我四岁就开始编程。我不记得有不使用计算机或不编程的日子。我的整个童年就是在不断编程和使用计算机。”
1994 年,15 岁时,Ficus 辍学并开始找工作。几个月后,他找到了一个全职编程工作,从此一直稳定工作。“在‘工作年限’上,我比同龄人多了七年,因为那些同龄人在 22 岁时才毕业。”
他来到了硅谷,并在各家公司之间跳槽,包括 Be,通常从事低层系统软件的工作。2000 年,在离开 Be 后,他加入了一家初创公司,但仅仅待了两天。在新公司工作的第一天,他意识到这里不适合他。“我意识到事情不对劲的第一个迹象是:我的电脑已经设置好了,而且我已经有了邮箱。他们是一家初创公司!”另外,他的整个团队那天都在外面开会讨论一个小的技术决策。Ficus 坚信应该马上动手写代码,而这家公司显然不是他想要的地方。第二天,他只去了公司一次,目的就是辞职。
Hiroshi Lockheimer,从 Be 就认识 Ficus,听说他在找新机会,于是把他推荐给了 Danger,Hiroshi 最近刚加入了那里。Ficus 加入了 Danger,负责内核和驱动程序,帮助构建 Hiptop 手机的平台。
到了 2005 年中,Ficus 离开了 Danger,搬到了 Seattle。Andy 邀请他加入 Android。对 Ficus 的部分诱因是共同创始人 Nick Sears 也住在 Seattle,因此 Ficus 可以留在那里远程工作。
Ficus 加入了团队。一周后,Google 收购了 Android。
Ficus 记得:“当 Andy 说‘公司会被 Google 收购’时,我想‘哇,这可能是我唯一能进 Google 的机会。’然后他说‘我们得去面试’,我想‘好吧,完了,结束了。’”
Swetland 记得,“Ficus 宣称,如果有人问他任何东西的 Big O^(12) 是什么,他就会直接说,‘我太帅了,没法回答这个问题。’”
但面试对 Ficus 来说很顺利,他加入了 Google,并最终搬回了湾区,以便离团队的重心更近。他一直偏爱从事低层系统软件的工作。从头开始构建 Android 操作系统为这种工作提供了大量机会。
第四章:投资展示

到 2005 年中,Android 被收购,未来看起来一片光明。但仅仅六个月前,情况并非如此乐观。那年 1 月,这家初创公司急需资金,他们的主要任务和大多数初创公司一样:获得资金。在从相机操作系统转向开源手机平台之后,他们仍然面临着真正构建产品的艰巨任务,这意味着他们需要更多的资金来雇佣足够大的团队来完成工作。
因此,公司专注于三件事。首先,他们需要一个演示来展示可能性。接下来,他们需要阐明他们的愿景,并制作一份演示文稿来帮助解释这一愿景。最后,他们需要将演示和幻灯片文稿带上路,向潜在投资者推销他们的故事。
演示时间
Fadden 加入时的第一个任务是巩固演示,完善 Swetland 和 Chris 一直在开发的原型手机系统。这个系统实际上并不可用(例如,它在主屏幕上显示一个股票行情,使用了一组硬编码的符号和过时的数据)。但该演示代表了产品在实际实施时可能的样子。

最初的演示由 Brian Swetland 和 Chris White 编写,后来由 Fadden 进行了增强,展示了一个主屏幕和几个应用程序(其中大多数并未实现)。这与现代 Android 主屏幕相差甚远。
Fadden 在演示中添加的一个应用是一个简单的日历应用。这一早期的演示项目最终成了他心头的痛。经过多年在 Android 平台上的工作,他最终帮助开发了 Android 日历应用。时间不等人……但日历应用会。
移动机会
随着团队不断完善他们的愿景,他们制作了一份幻灯片演示文稿来解释这一愿景。这些幻灯片展示了他们在市场上为 Android 看到的机会,以及 Android 如何为投资者带来收益的构想。
2005 年 3 月的幻灯片文稿有十五张幻灯片,足以引起风险投资者和谷歌的关注。
投资展示文稿在第二张幻灯片开始变得有趣,比较了 PC 和手机市场。2004 年,全球 PC 出货量为 1.78 亿台。同一时期,手机出货量为 6.75 亿部;手机出货量几乎是 PC 的四倍,但其处理器和内存的能力与 1998 年的 PC 相当。
移动硬件的潜力是 Dianne Hackborn 当时在 PalmSource 工作,后来加入 Android 团队时也在思考的一个问题。移动行业已经准备好爆发,因为硬件终于足够强大,可以提供一个真正强大的计算平台:Dianne 说,“你可以看到墙上的字。硬件变得更强大,市场已经比 PC 更大了。”

演示文稿的第一页。那种定制字体的“ANDROID”字样在这次创业阶段后多年仍然是该操作系统的标志。

到 2004 年,手机的数量已经远超个人电脑的销量,这为拥有更强大软件的手机提供了巨大的机会。
演示文稿还指出了移动软件成本日益增长的问题。硬件成本在下降,但软件成本却没有下降,导致软件在每部手机成本中的比例越来越大。然而,手机制造商并非软件平台开发专家,他们既没有相关技能,也没有兴趣提供区分自己软件与竞争对手软件的所需功能。
开放机会
演示文稿中的第二个主要观点是,市场上存在一个空白和机会,可以推出一个开放平台。也就是说,Android 将是一个自由且通过开源提供给制造商的操作系统。公司可以在自己的手机上使用并分发这个操作系统,无需依赖软件提供商,也无需自己构建。这样的开放方式在当时是根本不存在的。
微软提供了一种专有操作系统,制造商可以授权使用并移植到自己的硬件上。Symbian 主要由诺基亚使用,索尼和摩托罗拉也有一定的采用。RIM 则有自己专属的平台,仅用于其 BlackBerry 设备。但对于那些希望拥有功能强大智能手机的制造商来说,市面上并没有替代选择,他们既不想自己构建操作系统,也不想投入大量精力定制现有操作系统,或支付高额授权费用。
更加严重的问题是,现有的系统未能为应用程序提供一个完整的生态系统。Symbian 提供了一些操作系统的核心基础设施,但 UI 层则交给了制造商处理,这导致了一个应用程序模型,其中为某一版本的 Symbian 编写的应用程序未必能在同一制造商的其他版本手机上运行。

第 7 页图示了开放平台的潜力,提供了当时其他地方无法获得的东西。
作为在服务器和桌面 PC 领域被称为“一次编写,到处运行”的 Java 编程语言,可能本来可以提供这种跨设备应用程序的能力,但 Java ME^(1)在移动领域远远没有达到这种水平。虽然它确实在不同设备间提供了至少相同的语言(就像 Symbian 为其所有实现提供了相同的 C++语言一样),但 Java ME 通过提供被称为profiles的不同平台版本来解决手机中各种形态因素和架构的广泛差异。这些配置文件具有不同的功能,因此开发人员需要更改其应用程序以在不同设备上运行,而在设备功能差异显著时,这种方法通常会失败。

TI 提供了一个基于 Linux 的解决方案,但许多驱动程序和其他组件的详细信息留给制造商去解决,这并不是一个令人信服的选择。
救星 Linux! . . . 差一点。德州仪器(TI)提供了基于 Linux 操作系统内核的开放平台。所有制造商所需的只是 Linux 本身,TI 的参考硬件,以及来自 40 个不同供应商的大量其他模块,制造商必须获取、许可、构建或以其他方式提供以创建自己的设备。正如 Brian Swetland 所说:“你可以使用 TI 的 OMAP^(2)芯片来打造 Linux 手机。因此,你需要 TI 的 OMAP,然后还需要来自四十个不同中间件供应商的四十个组件。你将所有这些组件整合在一起,然后你就有了一个 Linux 手机。这实在是太荒谬了。”
安卓希望提供全球第一个完整的开放式手持设备平台解决方案。它将建立在 Linux 之上,类似于 TI 的提议,但还将提供所有必要的组件,以便制造商只需采用一个系统即可构建和推出其设备。安卓还将为应用程序开发人员提供一个统一的编程模型,以便他们的应用程序在平台运行的所有设备上都能同样工作。通过拥有一个在所有使用该平台的设备上都有效的单一平台,安卓将简化制造商和开发人员的手机开发过程。
赚钱
融资的最后一部分(对于他们向风险投资者进行的演讲来说,这是最重要的部分)是关于安卓如何赚钱的。在幻灯片中描述的开源平台基本上是安卓团队最终构建和推出的内容。但如果仅此而已,公司将不值得风险投资者投资。从拯救世界的角度来看,开发并免费提供开源平台听起来很好,但利润在哪里?对投资者来说,这有什么好处?也就是说,安卓计划如何从他们计划中简单地提供的产品中赚钱?风险投资家资助那些他们希望能带来比他们投资回报更多(远远更多)的公司。
对于游戏中的其他平台公司,通向收入的道路是清晰的。微软通过将其平台授权给 Windows Phone 合作伙伴来赚钱;每卖出一部手机,微软都会收到每部设备的费用。RIM 通过销售手机以及他们的忠实企业客户签署的有利服务合同来赚钱。诺基亚和其他采用 Symbian 的公司通过销售他们制造的手机(这些手机使用了该操作系统的不同版本)来赚钱。类似地,所有其他手机制造商通过他们销售的手机产生的收入来资助自己的软件开发。
那么,Android 的策略是什么呢?他们如何资助这个尚未建立的强大平台,并且会将其免费提供给其他制造商,让他们制造自己的设备?
运营商服务。
运营商将为 Android 手机提供应用、联系人以及其他基于云的数据服务。运营商会为提供这些服务向 Android 支付费用。Swetland 解释道:“我们不会像 Danger 为其 Hiptop 手机所做的那样运行和托管服务,我们会构建这些服务并将它们卖给运营商。”^(3)

第 11 张幻灯片展示了通向利润的路径,基于运营商将从 Android 授权的服务。
推销梦想
Android 团队向一些风投推介,主要是在东海岸,远离硅谷。正如 Rich Miner 所说:“Andy 曾多次走上 Sand Hill Road^(4),以 Android 作为相机操作系统进行推介,已经收到了一堆‘不行’的答复,其中包括 Red Point 那里,他曾是 EIR(驻场创业者)。我加入的部分原因就是想说,‘我有一堆东海岸的风投和其他人,可以介绍给你们。’所以我们开始去见一些之前没听说过 Android 的人。”
与这些风投会议并行,团队还在与 Google 进行会谈。今年 1 月初,Larry Page^(5)邀请 Andy 到 Google 开会。Larry 是 Andy 之前公司制作的 T-Mobile Sidekick(Danger Hiptop)手机的忠实粉丝,因此他希望与 Andy 讨论移动领域的事情。Andy 打电话给仍在 T-Mobile 工作的 Nick Sears,邀请他也来参加这次会议。
这是一次小型会议,只有来自 Android 的 Andy 和 Nick,以及来自 Google 的 Larry、Sergey Brin^(6)和 Georges Harik(Google 的早期员工)。Nick 记得这次会议非常随意,但也明确感到 Google 对 Andy 和 Android 正在做的事情非常感兴趣。“会议开始时,Larry 说 Sidekick 是有史以来做得最好的手机。Larry 非常希望看到一款更好的手机被制造出来,而他知道 Andy 和我们团队正在致力于这项工作。会议结束时,他们说:‘我们希望能帮助你们。’”
那次会议令人鼓舞,但没有取得任何实质性的成果。事实上,安迪怀疑他们是否只是把这次会议当作一种方式,想要从安迪那里了解他在 2003 年创办并离开过的公司 Danger 的情况。他认为谷歌可能有意收购 Danger。
与此同时,团队继续向风险投资公司(VC)进行推介。然后在三月,他们前往谷歌进行另一次会议。这一次,他们展示了一个演示并分享了更多的计划。虽然这次会议也没有发生什么重大事件,但谷歌更明确表示他们希望帮助这家初创公司。
此时,团队还在与潜在的制造合作伙伴进行会谈。他们前往韩国和台湾,拜访了三星和 HTC。与三星的会议开始时,手机部门的首席执行官李健熙说他错失了与 Danger 合作的机会,不希望再发生这种事,因此他有兴趣加入 Android。尼克描述了这次会议:“李健熙告诉他的团队让它成真,我们以为这是一笔已成的交易。但随后我们与他 10 多位中层经理开会,他们问,‘谁来打造你们的操作系统?’我们说‘布赖恩’,他们笑了。他们有 300 人在开发他们自己的操作系统。”
三星问团队是否是在做梦。尼克回答说:“不,真的,布赖恩和其他几个人将会打造这个操作系统。”他们问这怎么可能实现,我们回应说不仅可能,而且布赖恩已经在 Sidekick 上做到了。
商务会议结束后,三星举办了一场晚宴以庆祝新合作关系。然而,Android 团队后来得知,交易的达成还取决于是否能从运营商那里拿到订单,尼克承认,“那根本不算一笔交易。我们花了大约 18 个月才说服 T-Mobile 成为我们的 Android 启动合作伙伴。”
团队没有带回一个正式的交易,但他们确实从中获得了一个设备名称。后来,当他们选择成为 G1 的设备时,他们给它取了代号“Dream”,以纪念那次会议。
从韩国,团队飞往台湾,与 HTC 的首席执行官周永明会面。尼克回忆起这次会议:“周永明提到关于我们第一款设备的独占性,这被布赖恩听到了。当我们回到酒店房间时,斯威特兰威胁要辞职,因为‘我加入 Android 不是为了变成另一个 Danger。’^(7) 我很担心,因为布赖恩对我们的成功至关重要,但第二天见到他时,一切都没问题。”
团队继续向风险投资公司推介并取得了一些成功。Charles River Ventures 和 Eagle River Holdings 都表现出兴趣。就在他们等待这些公司的文件时,谷歌邀请他们进行第三次会议。
这次,房间里有更多的人,Google 准备好讨论具体细节了。安迪和他的团队原本以为他们是来更新自上次会议以来公司进展的。但在展示过程中,尼克记得,“他们只是说,‘让我们打断一下。我们只是想收购你们。’”
Google 将安迪团队认为是 Android 向 Google 推销的会议,转变为 Google 向他们推销的会议。Google 表示,如果 Android 愿意被收购,它将比原本独立发展时做得更好。Android 不需要再应对风险投资者的要求,也不必向客户和运营商收取专业服务费,他们可以直接将操作系统免费提供给运营商。事实上,这甚至比免费还要好:Google 通过搜索获得的收入,可能可以与运营商共享。因此,他们不再需要向运营商推销某些东西,而是可以与运营商建立合作伙伴关系。尼克记得,这是一个说服运营商加入的有力论点:“我们实际上是在通过与我们达成合作伙伴协议来帮助他们赚钱。”
Android 团队愿意加入 Google,但仍有许多细节需要解决。与此同时,在四月中旬,他们收到了来自 Eagle River 和 Charles River 的条款清单,并决定选择 Eagle River 的交易。Google 的交易距离最终确定还很远,但在五月初已进入谈判阶段,因此他们在条款清单中添加了一个 carve-out^(8),以应对他们可能会与 Google 达成协议的情况。
第五章:收购

他们买下了一支团队和一个梦想。我希望相信我们在这方面执行得相当出色。
—布莱恩·斯韦特兰德
当 Android 团队与 Google 会面时,拉里·佩奇观察到,Google 收购这家小公司是合乎逻辑的,这将帮助他们构建一个平台,使 Google 能够进入移动市场。
尽管双方原则上达成了共识,但仍有许多细节需要解决。Nick 回忆起 Android 需要与 Google 解决的两个大问题。第一个是资金问题:他们需要就公司的估值和支付方式达成一致,包括初始支付和团队加入后持续的里程碑支付。第二个问题是承诺:Android 希望确保他们能够真正实现最初的目标,而不是被吞并进更大的公司后被遗忘。他们需要 Google 承诺,在收购后继续支持 Android 的努力,并提供持续的内部支持。
谈判始于 2005 年春季。但 Rich Miner 遇到了一个问题:一次家庭度假与这些时间紧迫的会议发生了冲突。他最终将两者同时进行,从英国维尔京群岛的一艘帆船上参加会议。“我必须找到有手机信号的港口。在这两个小时的电话会议期间,我得让所有人都上岸去海滩享受时光,只有我一个人在船上。”
“我们担心的一件事是,‘这对 Google 来说没有战略意义。你们甚至没有开始关注 WAP^(1)或任何移动相关的事情。我们认为这将会非常费力,需要大量资源。如果你们不想做这件事怎么办?我们怎么知道能得到成功所需的资源?’”
拉里·佩奇建议他们去与负责产品和市场的 Google 高管 Jonathan Rosenberg 谈谈。Rich 记得他的建议:“‘Google 与其他公司不同。很多公司,当项目进展不顺利时,他们会投入大量资源。而在 Google,我们更愿意将资源投入到顺利进行的项目中。所以,如果你们按照计划执行,表现好,就会得到更多的资源。’这本质上就是他的信任跳跃演讲;如果我们相信自己,就应该做这件事,因为如果我们执行得好,就能获得资源。”
Android 团队回到了谈判桌(和船上),达成了协议,团队于 2005 年 7 月 11 日开始在 Google 工作。
在安卓团队加入谷歌几周后,他们再次展示了演示文稿。这一次是在谷歌的一次内部会议上,向一群高管展示。安迪和其他团队成员展示了这个新收购团队的计划。斯韦特兰描述了这次会议:“我们展示了我们做的演示。安迪正在逐页讲解。我记得当他讲到盈利模式时,拉里打断了他,说:‘不用担心那个。我希望你们做出最好的手机,其他的事情我们以后再想办法解决。’”
第六章:Google 的生活

所以,Android 团队现在已经在 Google 了。他们要做的就是招聘大量的人,完成其余的产品构建,并将其推向市场。轻而易举!
其实并非如此。实际上,Android 在 Google 的起步几乎与它在 Google 之外的存在方式一样:它是一个小型的、保密的项目,没人知道这回事。他们只是在门禁控制的另一侧工作而已。Android 并不是为了补充一个已经在做这项工作的现有团队而被收购的;他们是被聘来启动这项工作的。
这时,Android 团队只有八个人,其中只有一半的人实际上在编写代码构建产品。他们需要弄清楚如何从一个向投资者推销的小型初创公司成长为一个建设和交付产品的部门。
这一过渡过程的一部分是要在新公司中找到自己的定位。Tracey Cole 表示:“我们在 41 号楼的走廊里待了很长时间。这很奇怪。他们有点把我们丢在一旁。”
Swetland 表示同意:“最重要的是,最初的一两个月,我们只是在摸索如何站稳脚跟。我们从一个十人团队的初创公司变成了一个有 4500 人的公司。我们前两周一直在会议室里露营,因为没有为我们分配固定的办公室。我们该在哪儿工作?我们如何招聘人才?”
招聘是下一个步骤:Android 需要更多的人。然而,在 Google 招聘 Android 工程师证明是一件困难的事。
Google 的招聘
Google 在科技界一直以其招聘流程而闻名。那时,硅谷主干道——101 号高速公路两旁的广告牌上展示着一个神秘的数学难题:

这个方程式曾在那时出现在硅谷 101 号高速公路上,迎接着司机们的到来。
这个难题让司机们困惑不已。没有提到 Google,只是一个难题,成功解答的人将被引导到一个面向程序员的招聘网站。
一个足够幸运的工程候选人,如果能让自己的简历通过招聘人员的筛选并进入系统,通常会面临多轮面试,包括电话面试和与不同工程师的面对面面试。
Google 一直相信,聪明的软件工程师可以做任何类型的编程工作。这就是为什么精通 3D 图形的工程师最终会参与到日本文本实现工作的原因。他们的技能和经验让他们获得了面试机会,但他们最终从事的工作是基于需要完成的任务。^(1)这也是为什么 Google 的面试测试计算机科学基础知识(算法和编码)的原因。这些面试跳过了其他公司认为是必要的步骤:对候选人的领域专业知识和简历上的亮点进行严格筛查。^(2)
这种方法通常对谷歌有利,因为谷歌的大部分软件都基于类似的系统,因此工程师可以顺畅地从一个小组转到另一个小组。这一切都只是软件,任何特定的产品知识都是聪明的工程师可以在工作中学到的。因此,谷歌招聘聪明的工程师时,并不特别要求某一领域的技能,而是认为他们可以在进入谷歌后学到完成工作所需的技能。
这种招聘方式对 Android 并不奏效。例如,擅长为服务器上的数据分析创建算法的工程师,可能完全不知道如何构建操作系统,或者如何编写显示驱动程序,或者如何优化图形操作、UI 代码、或网络功能。这些话题并不一定出现在大多数本科生学习的计算机科学基础课程中,而且在工程师进入谷歌面试之前,通常也不会出现在他们的典型工作中。法登说:“我的一位面试官告诉我,谷歌可能不会聘用我,因为我‘太基础’了。我们招募设备 UI 人员时遇到了很多困难,因为这与网页 UI 很不相同。”
构建像 Android 这样的平台所需的技能,是通过人们因为对这些特定领域的热情而从事的工作和兴趣项目中发展出来的。编写操作系统的工程师是那些想要编写操作系统的工程师。虽然这个主题有相关的课程教授,但并不是每个人都会去学习,且这些课程往往是简略的;只有那些真正热爱操作系统开发的人,才会在课堂外的工作和项目中学到他们所需的技能。
Android 需要的是专家;没有足够的时间来培训一支庞大的通才团队。为了让项目在当时竞争激烈的移动领域中有希望取得成功,Android 必须尽快交付一款成品。他们需要快速构建平台,这意味着他们需要招聘可以立即投入工作并开始行动的领域专家。但擅长编写操作系统的专家,不一定能顺利通过谷歌的通才面试。
另一个问题是,当时谷歌也期望员工具备学术背景;公司更倾向于从顶尖工程学校和知名学校招聘候选人。那些拥有丰富经验,但教育背景非传统的专家并不符合这种标准,往往难以通过招聘流程。这给早期的 Android 团队成员带来了问题,他们并没有谷歌招聘人员所期望的学术资质。许多人甚至根本没有大学学位,更别提来自顶尖工程学校的学位了。Fadden 说:“一位有超过 10 年行业经验的老兵因为本科学位的 GPA 不够高而被拖延了招聘过程。对于一个偏爱斯坦福博士的公司来说,收购一个只有一名工程师毕业于大学的创业公司,真是一个很大的转变。”
当时在谷歌开源办公室工作的 Chris DiBona 被请来帮助解决招聘问题。
Chris DiBona 与招聘解决方案
Chris 自己的学术经历并不顺利;他在离开大学时只剩一门课没上^(3),那时他已经搬到加利福尼亚。几年后,他成为了该地区 Linux 用户组的社区组织者,这最终让他在 2004 年被谷歌注意到。经过十三次面试和三天的时间,Chris 开始了在谷歌的工作。
Chris 成为了谷歌招聘委员会的常驻成员,这些委员会根据应聘者面试反馈做出招聘决策。“我被视为一个有用的人。如果他们太宽容,我就是那个严厉的人;如果他们太苛刻,我就是那个宽松的人。所以他们会把我带进来,平衡招聘委员会。我与招聘人员和管理员是朋友。”
Chris 的经理问他:“你能帮助 Andy 解决招聘问题吗?”
Chris 已经在谷歌的另一个团队经历过类似的困难:那个团队是“系统与平台”团队。该团队也在寻找像 Linux 内核开发者这样的专家,因此 Chris 对如何解决问题有了一些想法。
“我们成立了这个‘平台’招聘委员会,专门负责那些特殊的招聘——这些人可能专长某一领域,但范围较窄。但我们需要他们。”
Chris 带着 Andy 去了那个招聘委员会,开玩笑地对他说:“当招聘人员说,‘不不不,这个人太专门化了,我们需要能做各种事情的人,’你就告诉她,‘如果他们想离开我的团队,我就解雇他们。’”
Andy 实际上并没有对招聘人员说这些话,也没有因为某些人过于专门化而解雇他们。无论如何,这并不会成为问题;谷歌在发展,并且对各类工程师的需求会越来越大,Android 团队和其他团队都会有需求。因此,他们鼓励招聘人员接纳这些人,结果也确实奏效了。在第一年,这个委员会为谷歌招聘了大约 200 人,其中许多人加入了 Android 团队。Android 团队所需要的技能人员通过这个更为专业化的招聘委员会进行筛选。
然而,让人通过招聘流程只是问题的一部分。还有一个额外的难题,就是如何吸引到合适的人才来申请。当时,Google 以搜索和广告闻名,还有一些像是去年刚推出的 Gmail 等 Web 应用。正如 Dianne Hackborn 所说:“我从没想过要去 Google 工作,因为我不关心搜索和 Web 那些东西。”Joe Onorato(曾与 Dianne 一起在 PalmSource 工作,后来加入了她在 Google 的框架团队)也表示:“当我在 2005 年申请 Google 时,我女朋友问我,‘Google 怎么有那么多人?他们有一个网站,只有一个文本框和两个按钮!’”^(4)
此外,Android 仍然是一个保密项目。即便在 Google 内部,大多数员工都不知道这个项目的存在。
Google 的 Android 团队无法公开宣布他们在寻找开发者来帮助编写操作系统、开发者平台,甚至是手机。后来,关于公司正在开发“Google 手机”的传闻开始流传,但那时传言者所知道的也仅限于此,而团队被禁止谈论此事。相反,他们会悄悄联系以前的同事,告诉他们应该申请加入。
Mathias Agopian(Dianne 团队中的另一个成员,曾在 Be 和 PalmSource 工作,2005 年底加入 Android)谈到了口碑招聘的过程:“那些曾在 Be 工作的 Android 人就像是,‘你一定得来!’但他们无法告诉我们他们在做什么。‘就来吧!’” 一旦 Mathias 和其他 Dianne 团队的成员加入 Google,他们也以类似模糊的方式招募 Dianne:“他们来找我说,‘你应该来 Google——这里有非常酷的事情发生!’”
David Turner 于 2006 年加入该项目,他在面试时能够感知到更多的信息:“我面试的很多人都是 Android 团队的工程师。他们不想告诉我为什么我应该加入公司,所以我问他们以前在其他公司做了什么,然后……他们告诉了我。所以在六次面试之后,我有了一个很好的感觉,Google 确实在启动一个新的智能手机或 PDA 项目。”^(5)
Tom Moss 和东京的招聘
Android 招聘的困难情况并不限于位于山景城的总部,创造性的解决方案也不仅仅局限于此。
Tom Moss(当时负责 Android 的业务发展)在日本待了几个月。Tom 表示:“我们知道比赛的关键是规模化,要做到这一点,我们需要走向国际化。我们选日本作为第一个验证点。” Tom 在日本的工作包括与 OEM^(6)厂商和运营商达成合作、向当地开发者宣传、为平台寻找本地内容等。他还负责招聘,招募能够将平台本地化为日本市场的开发者,以及处理相关的工程工作。
他承担这个角色既是为了帮助该地区的一些合作伙伴关系,也为了为团队引进更多的工程人才。除了正常的招聘困难之外,日本办公室的候选人不仅需要是顶尖的工程师,还必须流利地讲英语。这个语言要求使得候选人池比原本更小了。对于 Android 来说,日本的外部招聘根本行不通。
为了鼓励内部员工申请 Android 的空缺职位,Tom 在谷歌日本办公室做了一场技术讲座。他介绍了 Android 及其团队文化,并指出 Android 是谷歌的重点项目。通过直接与工程师交流,他迅速从地图和 Chrome 等其他团队招聘了几位工程师。
尽管在找到合适的候选人并让他们通过流程方面遇到了困难,但招聘过程并非全然不顺利;谷歌愿意采取创造性的方法来吸引合适的人才。Mathias Agopian 实际上在面试谷歌时,原本计划去苹果公司。“我在面试谷歌的同时,也在面试苹果。他们甚至给了我一个 offer,我接受了。那将会是图形团队的职位,在 iPhone 推出之前。我当时非常高兴,因为我以为终于可以重新做桌面相关的工作了。BeOS 是一个桌面操作系统。我其实并不太喜欢那种移动设备的东西。”
“但由于我的签证问题,他们撤回了 offer。我正好快到六年的 H1-B 签证限制期了。为了留在美国,他们需要为我办理绿卡,而这很复杂。”
“谷歌的做法正好相反。我最初告诉他们我的签证情况很复杂,他们说,‘没关系——先面试吧。’我参加了面试,他们给了我 offer,然后我才解释了情况。他们说,‘我们以前没遇到过这种情况。这确实有挑战性。’他们没有说‘这太难了’,而是说‘这挺酷的!’他们还说,如果不行,我可以在欧洲工作一年。我甚至收到了来自苏黎世办公室的备用 offer!”
第七章:系统团队

系统团队负责软件堆栈的最低层。你可以把他们的工作理解为将手机硬件(如 Sooner、Dream/G1、Droid,以及团队参与过的其他设备)与每个设备上运行的其余软件连接起来。
在 Android(或任何操作系统)上运行的所有内容的最底层是内核。内核是实际硬件与系统其他部分之间的接口, plus 操作系统必须执行的一切任务(如启动系统、创建进程、^(1)管理内存以及处理进程间通信)。如果一部手机是一个房子,那么内核就是基础、线路和墙壁中的管道,它们发出的“滴答滴答”声会让你在半夜醒来,难以重新入睡。
硬件通信由内核中的设备 驱动程序 处理,驱动程序是与设备上实际硬件进行通信的软件模块。例如,为了在屏幕上显示像素,驱动程序在图形软件(它负责计算每个像素的颜色,以便显示图像、文本和按钮等)和物理屏幕硬件之间进行转换。同样,当用户触摸屏幕时,这一操作会转化为原始硬件信号,指示触摸的位置。这些信号会作为触摸事件传入系统,然后由软件进行处理,包括希望处理这些事件的应用程序。
系统组的一个基本任务是启动,即从拥有一块硬件(比如一部手机,或者甚至是一个手机原型,包含一系列芯片、电路和显示屏)到能够启动 Android 操作系统的过程。
Brian Swetland 和内核
由于 Swetland 在低层系统方面的背景,以及他是第一个加入的人,因此从第一天起,他就自然地领导了 Android 系统团队。Brian 在收购前就已经开始工作并领导系统团队;他在加入 Google 后继续担任这个角色,随着团队的壮大,仍然负责这个工作。
系统团队的主要工作是让内核在早期的 Android 设备上运行,并为每一款新 Android 设备提供支持。^(2) 当 Android 还是一家初创公司时,内核只需要足够好,以便演示可以运行。但在团队进入 Google 后,他们需要转向构建一个真正的产品:一个完整的操作系统和平台,基于一个坚实的内核。
幸运的是,Swetland 确保了早期的原型内核为后续开发提供了一个不错的起点:“我所做的一切都是朝着最终成为产品的方向进行的。我不相信做完全是一次性的演示。我们当时没有流程分离,^(3) 但我们知道那将走向何方。我们仍然需要内核、引导加载程序、^(4) 图形驱动程序以及所有东西。我们在过程中做了一些演示性质的事情,但我们始终试图规划一条道路,让它不是纯粹的演示。它是朝着一个系统前进的进展。”
Swetland 对 demo-ware 的看法源于他在以前公司中的经历,那时商业部门的人误解了优秀的演示和实际产品之间的区别。“构建纯粹的 demo-ware 的危险在于,某人决定将其发布。然后你就麻烦大了。”
所以,Swetland 负责开发 Android 要建立在其上的内核:“我们继续使用那个[演示用的内核]。它基本上是现成的 Linux 内核,然后在其上进行驱动程序工作。Linux 主线^(5) 中有一些我提交的补丁,上面有我的名字,是在我加入 Google 后提交的。我们在早期并没有太多考虑将东西上游化^(7)。”
与此同时,Swetland 和他的团队开始看到成为 Google 一部分的一些实际优势。在加入 Google 之前,“作为一家小公司与 TI [德州仪器] 合作推进,确实有些痛苦。得到的支持远不如后来从 Google 得到的。” 然后,在加入 Google 后,“从供应商那里获得支持变得极为容易。意外,意外。人们不再讨论我们需要支付多少费用来获得开发板。他们会主动给我们提供硬件,这真的很不错。这就是 Google 的一个大优势,成为一个被认可的品牌,而不是一个默默无闻的小初创公司。人们愿意接起电话并回答你的问题。我们仍然在一些地方需要争取支持,但情况本可以更糟。”
Brian Swetland 的传奇之一是他在 G1 发布前不久“发现”了额外的内存。他在发布前提交了一个修复,扩大了设备上可用的 RAM 从 160MB 增加到 192MB,为操作系统和所有应用程序提供了 20% 更多的内存,这对于这个内存极其紧张的系统来说是一个显著的提升。
诀窍在于他知道在哪里找到那块内存,因为它最初就是他藏起来的。内核负责让其他系统可以使用内存。当他首次在 G1 上启动内核时,他配置它报告的内存量比实际拥有的少。对于其他系统来说,实际上可用的内存比硬件物理上可用的少了 32MB。他这样做的目的是明确知道,如果内存是可用的,每个开发者都会使用它,但如果必须在更紧张的预算下工作,他们就会适应这种限制。
每个人都在这更小的内存池中使软件正常运行,因为那是他们唯一拥有的。当他在 G1 发布前释放了其余的内存时,这意味着可以同时运行更多的应用程序,因为他已将整个系统强行压缩到一个比实际需要的更小的空间。
后来加入团队负责蓝牙的 Nick Pelly 记得,并不是所有人都满意这种做法:“天啊,这给我们带来了多大的戏剧性效果。浏览器团队为了适应(虚假的)内存预算,已经连续好几个星期天都在加班。我记得有一个人怒气冲冲地冲进 Brian 的办公室,嘴里骂骂咧咧,当他‘发现’那额外的内存时。”
Ficus Kirkpatrick 与驱动程序
内核本身并不需要额外的人员来进行工作。这可能令人惊讶,考虑到内核的复杂性以及它在整个系统中的重要性。但 Linux 已经存在,在不够用的地方,Swetland 就负责解决。但是内核的驱动程序,另一方面,确实非常紧缺。系统需要各种各样的硬件,而这些硬件必须由内核来处理。所以当 Ficus Kirkpatrick 加入 Swetland 的团队时,他就开始忙于编写驱动程序,从相机驱动开始。
“我一直专注于操作系统和底层技术,这是我在进入 Android 时最擅长的核心领域。刚开始的第一两年[在 Android 上],主要做底层系统工作。我们决定使用 Linux,所以没有太多内核方面的工作。于是我做了很多驱动相关的工作。我做了第一个相机驱动,让它在 OMAP 上运行。^(8) 还让音频也能工作。” 一旦音频实现,“我们可以传递缓冲区,或者获取相机数据,那我们接下来要做什么呢?”于是,Ficus 开始着手媒体框架,创建了 API^(9) 和功能,使应用程序能够访问设备的新音频和相机功能。
Arve Hjønnevåg 与通信
早期缺失的驱动程序之一是无线电^(10) 硬件;新的手机操作系统无法进行电话通话。所以 Swetland 请来了一位擅长通信驱动的专家。
Arve Hjønnevåg 于 2006 年 3 月加入 Swetland 的系统团队。他在 Android 社区中因其…沉默而闻名。他的队友 Rebecca(几页后将出现)说,她有时会请他帮忙处理他们用于管理源代码的系统。她已经习惯了用“再说一次,更多的词”来回应他的回答。
一旦 Arve 使系统与无线电硬件进行通信,他便专注于电源管理。具体来说,既然硬件能够进行电话通话,它还需要在通话过程中保持清醒,不会进入睡眠状态。
当时,Linux 在服务器和桌面系统(包括笔记本)上表现出色。但它并不是为手机而设计的,需要新功能来处理这种新的使用场景。当你合上笔记本电脑的盖子时,你希望它完全进入睡眠状态。你不希望或不需要系统上有任何东西运行,直到你稍后再打开盖子。
但手机是完全不同的。当屏幕关闭时,你不希望它继续做你在主动使用时可能进行的所有操作,但你希望它保持足够清醒,比如,继续进行你正在进行的电话通话^(11),或者继续播放你正在听的音乐。
所以 Arve 向 Android 的 Linux 内核中加入了唤醒锁的概念,以确保屏幕关闭时并不意味着完全关闭。Android 会在屏幕关闭时强制让应用程序和大部分系统进入睡眠状态(因为电池消耗总是一个巨大的问题),但唤醒锁确保系统可以保持清醒状态,如果有事情需要继续进行,即使屏幕关闭了。

Arve 在 2007 年 10 月调试 G1 原型硬件,使用了 TEK 电池仿真器和几台预 G1 设备(“Sooners”)(照片由 Brian Swetland 提供)
Arve 将唤醒锁功能提交到了 Android 版本的 Linux 中。这个功能在 Linux 社区引起了些许波动,因为一些开源社区的坚定支持者将这个功能视为 Android 分叉^(12)Linux 内核的例证。Chris DiBona(他曾处理^(13)很多开源项目)记得在那个时候,他曾在一个 Linux 会议上与社区的人交谈。“有一个人怒不可遏,‘我简直不敢相信你们在做这个!’”
“我当时想,‘三年后,这将不再是问题。在此之前,Linux 社区要么接受我们当前形态的补丁,要么稍微修改它们,可能会换个名字,或者你就会抛弃市场上所有的移动设备。所以和我们合作,做出一个可以接受的方案。否则,我们将继续发布,因为这对我们来说,确保有一个良好的电池续航非常重要。’”
最终,Linux 并没有直接采用 Android 的唤醒锁实现,但他们确实实现了一个解决相同问题的方案。
Iliyan Malchev 和蓝牙
显示驱动程序是系统团队必须解决的另一个问题。如果无法看到操作系统的显示效果,那么即便是一个强大的操作系统也毫无意义。Iliyan Malchev 在加入团队后开始处理这个问题。
Iliyan 在八岁时就开始学习编程,那时他住在保加利亚,使用的是一种他不懂的语言。父母为家里买了一台电脑,Iliyan 开始玩弄它。“那太神奇了;我敲打键盘,屏幕上发生了事情——这才让我真正对编程产生兴趣。我当时不知道自己在做什么。这并不是说我马上就成了一个程序员。在保加利亚,一切都使用西里尔字母。而编程代码都是拉丁字母,比如程序清单。我既不会说英语,也不懂拉丁字母,所以我只能一个字母一个字母地抄。”
Iliyan 去美国上大学,后来在高通公司工作了几年。这段经历对他后来的 Android 工作,尤其是对系统团队的工作帮助巨大,因为 Android 设备大量使用高通的硬件。
Iliyan 于 2006 年 5 月加入了 Swetland 的系统团队。他的第一个项目是让副显示器工作:“[Swetland] 给我扔了一个有两个显示屏的翻盖手机。他说,‘让外部显示器工作。’作为 Swetland,他直接在没有任何文档的情况下将 Linux 系统启动在这台设备上。我猜他只是想给我点事情做,好让我不再烦他。”
在那个项目之后,Sooner 设备^(14)开始进入团队。Iliyan 负责让设备上的硬件输入正常工作:包括方向键(上/下/左/右箭头)和轨迹球。与此同时,他注意到 Android 系统越来越庞大,已无法适应设备有限的存储空间,而且系统持续增长,因此他花时间优化系统大小,以便让它能够适配。

配备硬件键盘、方向键和许多按钮的 Soonerc 设备
然后他开始研究蓝牙。这包括使蓝牙硬件的驱动程序能够正常工作,以及为应用程序提供与设备通信的蓝牙软件。“这是 Android 上的第一版蓝牙软件,而它……并不好。[蓝牙]是一个糟糕的标准。他们发明了一个像互联网一样规模和复杂度的东西,结果只是为了支持无线耳机。它被过度设计了。我做完这一部分后,将它交给了另一位工程师 Nick Pelly。Nick 接手了蓝牙堆栈并让它正常工作。他值得所有的荣誉。”
Nick Pelly 和蓝牙
Nick 在澳大利亚的大学学习计算机科学,但并没有认为自己会以编程为生。毕业后,他打算开始一份在 Telstra 的通信工程工作,并计划在全球旅行一年的间隙后回去。
但当他在加利福尼亚旅行时,他在 Telstra 的工作告吹了,所以他需要另寻出路。他一直对硅谷很感兴趣,所以他迅速在该地区投出了求职信息。只有一家公司回复了他:Google。幸运的是,他拿到了这份工作,并于 2006 年加入了 Google 搜索设备(GSA)团队。

Ficus 和 Iliyan 调试…… 2007 年 8 月的某个事情(照片由 Brian Swetland 提供)
GSA 是 Google 早期认为能够赚到钱的产品之一,当时他们的主要产品是搜索引擎。他们向公司销售一种机架式硬件,用来索引公司内部的文档。它将 Google 的互联网搜索能力扩展到公司的内部网站。但后来 Google 进入了广告业务,GSA 很快就不再是焦点。当 Nick 加入团队时,这个产品已经不像以前那样被积极追求,但 Nick 承认:“这对一个新工程师来说,是学习 Google 搜索堆栈的绝佳方式。”
2007 年夏天,他参加了 Android 团队首次向 Google 其他部门展示他们正在做的事情。Nick 被深深吸引。“我没有相关背景。我是团队中最早加入的几个人之一,我之前没做过消费电子产品,也没有做过像 San、Rebecca 和 Mike 那样从 Google 平台团队出来的人做过平台级别的工作。我只有一年半的专业经验。”
“但是我来到他们面前,说:‘这太棒了。我什么都愿意做,你们需要我帮忙什么?’”
“Brian 说:‘蓝牙!’”
“我知道他们太有雄心壮志了,最终会失败。我告诉我的女朋友和妈妈:‘根本行不通。但是这些人很棒,我会学到很多东西。’”
Nick 承接了蓝牙项目,并迅速掌握了它。“这真是一个陡峭的学习曲线,一旦我开始理解,就再也脱不了身了。”他不仅需要让蓝牙作为驱动程序工作,还要在 Android 的平台和应用层中让它正常运作。这个工作的最困难、也是最持续的部分,是要让它与世界上各种各样的蓝牙外设正确配合。
“大多数蓝牙外设都带有大量‘怪癖’(bug),而且永远不会得到固件更新。所以我们不得不绕过这些问题。我想出了一个简单的策略——每当发现一个蓝牙互操作性 bug 时,我就会购买该设备,加入到我桌子上的设备集合中,并把它纳入我的手动测试中。不久后,我有两张额外的桌子,堆满了蓝牙设备。我会保持它们都插着充电——这样我就不会丢失那些不常见的充电器,而且测试前也不需要等设备充电。多次,我不得不把这些设备清空,因为一旦听说有防火管理员的检查,我们得赶紧收起所有串联的充电器。”
“汽车套件有点难,因为你无法在办公室放下整辆车。但我很快发现,主要的汽车制造商很乐意给我寄来包含汽车信息娱乐系统核心部件的 Pelican 箱子,这样我就可以在办公桌上测试相关的硬件。这些箱子堆满了我的桌子,甚至溢出了走廊的角落。”
Nick 的经理是 Brian Swetland。像许多早期 Android 时代的经理一样,Swetland 并不太参与日常操作。这包括他抵制与团队成员的同步会议,正如 Nick 回忆的那样:“我记得几周后,我问我们是否会有 1 对 1 的会议。他似乎对这个问题不太高兴,但说我可以自己安排一个。我确实安排了,他迟到了十分钟,第一句话就是‘我#%&()#讨厌 1 对 1 的会议......’从那以后,我们再也没有开过 1 对 1 的会议。”
“然而,我记得 Brian 是我最喜欢的经理之一。他的系统知识无可匹敌。他在职责和范围上慷慨大方,并且没有微观管理。他全身心投入到手机的开发中,对员工非常忠诚且关怀。为 Brian 工作是我职业生涯中的亮点。”

2008 年 3 月,Nick 在办公室小睡。左上角是一个汽车信息娱乐系统,仍在汽车制造商提供的保护外壳内。(图片由 Brian Swetland 提供)
San Mehat 和 SD 机器人
百度高温,正值夏季,我看着这部电话,听着那个人一次又一次地说着废话。
—San Mehat
在驱动程序和系统启动方面,San Mehat 的帮助为我们带来了更多支持。San 于 2007 年加入了 Swetland 的团队,与 Nick 差不多是在 SDK 发布前的那段时间。
San 小时候通过在键盘上随机敲打来学习编程。他的父母在地下室开了一家电脑店,他就在那里的电脑上玩。“有一天我很沮丧,就开始猛敲键盘。结果不小心按到了 ctrl-C,屏幕跳出了一个提示框,我根本不知道那是什么。于是我开始输入一些东西,结果显示‘语法错误’。我当时就想,‘这是什么意思?’我再输入一些东西,它说,‘未定义函数错误。’我想,‘这是什么意思?’”他的表哥建议他输入‘LIST’,结果他正在玩的游戏的 BASIC 代码就显示在了屏幕上。
San 的编程学习方法最终成为了构建驱动程序的宝贵经验。编写硬件驱动程序的大部分工作就是弄清楚硬件能做什么,以及如何让它做那些事。这项工作大部分是实验,目的是理解硬件如何工作,和与它沟通的规则和协议是什么。San 从一开始就在自己家地下室的电脑上随便敲打,看看会发生什么,从而在摸索这些规则。
他在童年时期继续通过兴趣项目进行编程教育,例如破解软件版权保护机制。他这样做是因为当时加拿大的软件市场不发达,自己有限的游戏资源只能通过这种方式解决。他在高中期间继续编程,之后通过为芯片和其他硬件系统开发内核和驱动程序,始终在学习如何让软件与硬件进行对话。
San 没有上大学。讽刺的是,正是为了向孩子们展示上大学的好处而设立的实习项目,最终让他决定不去上大学。
他通过一个实习(后来转为暑期工作)与贝尔北方研究公司(BNR)一起做 CPU 模拟器,在那里他学习了新的编程语言和处理器内部原理。他对这项工作非常热衷,甚至想最终留在 BNR 工作,但他意识到自己的高中成绩永远无法让他进入那种能为他提供工作的大学。所以他决定跳过这一环节,自己独立完成,于是和一些朋友一起创办了一个互联网服务提供商(ISP)。在此过程中,他一直在黑客操作系统和各种硬件,积累了成为一名优秀驱动开发人员所需的技能。
“给我一块你不知道它如何工作的奇怪硬件,再给我一段能让它工作的软件。通过拆解软件和分析硬件,我可以反向工程并创建另一个有效的驱动程序。”
2005 年,San 加入了谷歌的平台组,负责为定制硬件编写驱动程序。2007 年,他转到安卓,加入了 Swetland 的系统团队。
“我加入是为了工作在 G1 上。最初,这个工作形式是‘frankenboard’,高通的‘surfboard’,这是一个大而疯狂的原型手机板,搭载了 MSM 芯片组^(17),并且进行了大范围的扩展。它看起来像一部手机,但被各种测试点搞得像是爆炸开了一样,可以将代码加载到里面并做各种实验。”

2008 年 2 月,San 正在对一块电池进行热测试(用打火机),背景中桌子上是用于 G1 处理器的高通“surfboard”。(图片由 Brian Swetland 提供。)
当他加入团队时,San 的主要工作是引导启动。“当时的引导启动是非常低级的工作,涉及到时钟控制、电源轨和电源控制。”那个第一个系统,G1,异常复杂。它实际上有两个CPU,一个由高通的控制芯片(ARM 9)控制,另一个由安卓(ARM 11)控制。启动 G1 需要先启动高通芯片,再启动安卓芯片。
“我的工作是弄清楚如何构建驱动程序。我必须弄清楚如何让这两者互相通信。然后接上时钟控制,接上电源轨道,以便我们可以开始启动外设,比如 SD^(18)控制器,以便 SD 卡能够启用,再比如图形控制器。所以我做了所有底层的琐碎工作,然后转向了 SD 卡。”
G1 的 SD 卡带来了一个有趣的问题。首先,SD 卡有两个不同的用途:存储和 Wi-Fi。SD 卡大多数被认为是可拆卸存储。但当时,SD 卡有时也被用来提供 Wi-Fi(卡上会有一个 Wi-Fi 芯片,而不是存储硬件)。
让 SD 卡工作很重要,因为它控制了这两个方面。但这很困难。“没有人(安卓团队的人)知道 SD 卡是怎么工作的。你无法获得 SD 卡的规格说明,因为要获得规格说明,你必须加入 SD 协会,而他们不会让你做任何开源的事情。^(19)所以我不得不对 SD 卡、SD 卡协议和 SD IO 协议(用于 Wi-Fi)进行逆向工程,并逆向工程大量驱动程序,弄清楚如何编写我自己的驱动程序。我花了几个月时间弄清楚如何让它工作。”
San 让 SD 卡正常工作(包括存储和 Wi-Fi),但出现了一个问题。G1 的 SD 卡对用户来说非常容易接触,因此可以随时插入或拔出。“有人决定将 SD 卡放在侧面,支持热插拔,是个好主意。如果你试着在 Linux 系统中插拔硬盘,你会发现这很麻烦。这是最糟糕的:设备几乎没有任何警告就被拔出。你可能正在写入磁盘。也许你三十秒前拍了一张照片,那些缓存数据仍然在操作系统页面缓存中,它们还不会被写入,可能还要等三十秒。”
G1 的 SD 卡槽有个盖子,用户必须先打开这个盖子才能拔出卡片。打开这个盖子会向系统发送一个信号,这个信号可以用作一个提示,快速让系统进入稳定状态,以防用户拔出卡片。但找到代码中需要执行此操作的所有地方是非常困难的。更糟糕的是,调试这个情况需要很多重复的拔卡操作。一次又一次,反复操作。最终,San 请求了帮助。
他联系了 Andy:“‘嘿,你对机器人感兴趣。我们有没有人能帮我做一个可以做这个的机器人?’他把我介绍给了某个人。我告诉他们我需要什么:一个小机器人,通过软件控制它的进出,然后我会创建一个闭环测试。这让我能够追踪到所有这些 bug。”San 利用 SD 卡机器人一个一个地追踪这些 bug,直到系统稳定运行。

San 的 SD 卡机器人,通过不断地将卡片插入和拔出插槽来强制发生崩溃,方便 San 进行调试(图片由 San Mehat 提供)。
G1 发布后:Sapphire 和 Droid
G1 发布后,San 开始了代号为“Sapphire”的设备开发工作,最终成为 T-Mobile G2 MyTouch。这个设备的主要任务是提升性能。“它慢得要死。虽然比 G1 稍微快一点,但与此同时,Romain^(20),真是好人,和平台及应用团队的其他人都在上面堆积着越来越厚的软件。所以切换应用时,总是卡顿和延迟。我花了很多时间在这个项目上优化内核。所以基本上就是不断地提升性能,重复这个过程。”
G2 发布后,San 的下一个挑战是摩托罗拉 Droid。他必须处理的一个问题是电源关闭场景,这个问题非常复杂。“这些小家伙们有大约三十个不同的电源域,它们都是单独控制的。要关闭设备,必须非常小心地依次操作:先关这个,等一段时间,再关这个,然后关这个,最后关这个……一路上,手机变得越来越傻。”
“Droid 的故障案例是这样的:手机进入休眠状态,或者你关闭它的时候,恰巧接到一个电话,结果手机根本不会响铃。我们会进入这些电源状态,然后停止监听调制解调器,因为我们会关闭它。调制解调器会试图唤醒我们,但我们不再监听调制解调器了;我们已经决定要睡觉了。所以我们睡着了,而调制解调器就在那边‘可是,可是,可是……!’”
“我们最终意识到,硬件缺少了一根线,它应该连接调制解调器和 CPU,用来告知 CPU 唤醒。”因为已经太晚了^(21),无法更改硬件,所以他们最终通过在其他系统组件的线路上发送唤醒信号来解决问题。
在工作中,San 还遇到了一个问题,涉及 Droid 的 Wi-Fi 系统,它导致视频播放时出现卡顿。“那次美国小姐选美比赛里有个关于‘男人与女人结婚’的非常有争议的评论。广志走进我的办公室,说,‘我们遇到了一个大问题,YouTube 视频在 Wi-Fi 下会卡顿。’我说,‘好吧,没问题,可能是 DMA^(22)的问题。给我一段参考视频。’”
广志给了他视频和故障发生的时间,恰好是美国小姐选美比赛中的那个尴尬片段。San 花了两天时间调试,反复听同一段视频。“每当我听到有人提到美国小姐时,我就会有一种强烈的[感觉],仿佛我正在沃尔纳特溪,气温有一百度,正值夏天,我盯着这部手机,听着这个人不断地说废话。”
Rebecca Zavin 和这款不被喜爱的设备
我们建了这个保险箱,只是忘了做墙壁。
—Rebecca Zavin
系统团队需要更多的支持来推动 1.0 版本的发布。Rebecca Zavin 于 2008 年初加入了团队。
Rebecca 开始编程的时间比她的许多 Android 团队成员要晚;她直到大学才真正接触编程。她一直认为自己会成为一名医生,于是去大学学化学工程,准备攻读医学院预科。然而,她在学习过程中发现自己讨厌化学。与此同时,她在大学的计算机科学系找到了一份工作,帮助设置计算机实验室。她开始越来越多地待在那个系里。一旦她开始上计算机科学的课程,就再也离不开了。
大学毕业后,Rebecca 进入了研究生院,最终加入了 Google,与 San 一起在平台团队工作。在 San 离开她的团队加入 Android 团队约一年后,Rebecca 也开始寻求新的挑战。“我想要有点不舒服,想要有点挑战。”她于 2008 年 1 月加入了 Swetland 的系统团队,距离 SDK 发布仅两个月,正好赶上了 1.0 版本的长时间推进。
在新团队的第一天,她就在办公室调试内核中的一个问题,直到晚上 9 点之后。“Swetland 当时说,‘好吧,这个肯定能成功。’”
团队刚刚发布了 SDK,现在他们需要让一切在真正的设备上运行。Rebecca 最初负责为 Android 开发显示驱动程序。Swetland 给了她一个最小化的驱动程序作为起点。在调试了一段时间后,她抱怨说驱动程序非常有漏洞。他告诉她这只是一个原型,实际上不应该使用它。她说,“我真希望你能告诉我这一点。我以为你知道自己在做什么。”
在成功让驱动程序工作之后,Rebecca 开始着手处理内存子系统,并在接下来的几年里继续工作。她的目标是让位数据通过系统流动时,复制的次数尽可能少(因为复制操作代价很高)。例如,当相机拍照时,会有很多像素存储在某个缓冲区中,这些像素需要传送到 GPU(图形处理单元),再到视频解码器,最后到显示内存。最简单的实现方法是将像素复制到每个新的子系统中。这样需要很长时间,而且会消耗大量内存,尤其是在那时的相机还比较有限的情况下。最终,她让系统实现了零复制。
在 2008 年底 G1 发布后,Rebecca 开始着手下一个设备:摩托罗拉 Droid。
Droid 是一个不被喜爱的项目和设备。团队的其他成员正在开发代号为 Passion 的设备,后来它成为了 Nexus One。Passion 将会是一款 Google 手机,拥有所有最新最强的功能,团队对此充满了兴奋。然后就有了这款摩托罗拉设备。
“Rebecca 说,‘没有人愿意碰它。它很丑。大家都对 Nexus One 很兴奋。至于 Droid?我们只能自生自灭。不久之后,它成了团队的大事,因为它成了第一个 Verizon 的发布。’”^(23)
“芯片组来自 TI,TI 有这些芯片的驱动程序。但是诺基亚有一版替代的驱动实现,Rebecca 建议他们应该从这个实现开始。”
“我们和摩托罗拉开了一个三方会议,我告诉他们,‘我认为我们不应该使用这个 TI 内核;它很乱。我觉得我们应该使用这个诺基亚内核。’然后我接到了 TI 销售员的电话,他说,‘摩托罗拉打电话给我,说你说我们的代码很糟糕。’”
“我说,‘我觉得我在会议中没有使用任何脏话。’”
那个尴尬的 root 漏洞
“早期 Android 开发的一个标志性特点就是团队执行的速度非常快。从零到 1.0 只用了三年,这真是令人吃惊,尤其是那个首次发布版本就包含了确保 Android 很快成为全球最广泛分发的操作系统之一的大部分基础功能。”
“我发现自己把咖啡洒到身上的概率和我移动的速度成正比。执行速度是有权衡的。在那些早期,大家都跑得很快,以至于有时忽略了在一个更小心、更慢的环境中本可以发现的问题。一个典型的例子就是那个著名的(至少在内部是)‘功能’,就是你可以从聊天应用重启手机。”
“Jeff Sharkey 和 Kenny Root 是 1.0 发布时的外部开发者(他们后来都被招聘到 Android 团队)。他们在那次发布之前就开始折腾 Android。Kenny 开发了一个 SSH 客户端(一个允许你登录远程计算机的应用)。Kenny 的版本是针对早期的、1.0 之前的 SDK 开发的。Jeff 更新了它,使其可以兼容后来的 Android 版本,并添加了更多功能。最终他们将它发布为 ConnectBot,这是 Android Market 上的第一个应用之一,^(24)至今仍是顶级 SSH 客户端。”
“当他们第一次开发 ConnectBot 时,他们收到了用户的一些奇怪的 bug 报告。Jeff 说,‘我们收到了一条奇怪的 bug 报告,有人说他们通过 SSH 连接到家里的服务器,输入 reboot 后,手机就重启了。我们以为他们一定是在抽什么东西,结果把它标记为不可重现。’”^(25)
“但这个漏洞实际上完全有效,而且对 Android 来说,的确有点可怕。”
“Rebecca Zavin 说,‘人们发现,如果你在 Gchat 中输入 root^(26),你就可以获得手机的 root 权限。然后人们意识到,当你输入 shutdown 或 reboot 时,它也能工作。’”
Rebecca 解释了这个 bug 是怎么产生的。“键盘事件被发送到一个一直打开的控制台。你总是想要有一个串行控制台^(28)。那很方便。所以我们把 root 控制台放在那里调试 . . . 本该做个记录去关掉它。”
“有一段时间,我们遇到一个持续存在的 bug,之前我们支持帧缓冲控制台,所以你可以切换到一种模式,看到日志,和你在 Linux PC 上一样。我们有一个经常出现的 bug,就是你会看到左上角有一个黑色方块。那是一个计时器问题。某个竞争条件^(29)会导致光标在你返回图形界面时闪烁。所以我会听到 Steve Horowitz [对我说],‘那个黑色方块。我有一个黑色方块!’
“在花了很多时间试图修复这个问题后,我想,‘我们干脆关掉帧缓冲控制台算了。我们为什么要在设备屏幕上看到内核日志?这太傻了。关掉它,我们就不用再处理这个问题了。’
“但是当我们关掉控制台时,它仍然在那儿[只是看不见]。我们都像是:‘糟糕,哎呀!’
“我们建了这个保险箱。我们只是忘了加墙。”
Jeff 说,“输入 reboot 命令到 ConnectBot 的人,实际上是在将它同时输入到他们的远程服务器和手机上,这解释了意外重启的原因。”
Nick Pelly 记得那个 bug:“我们以为那是某个聪明的黑客搞出来的微妙技巧。结果不是,不是:你每按下一个键,都会进入 root shell。”
Kenny Root 补充道,“这可能为 G1 的第一个‘root’打开了道路,但我保证那不是以我名字命名的。”

Rebecca 在 2008 年 3 月调试(照片由 Brian Swetland 提供)
还有其他一些例子,Android 在过程中错过了某些细节;大家都在非常非常快地奔跑,忙于把事情做起来。幸运的是,平台足够持久,团队能够随着时间推移回过头来修复这些问题。至少是我们知道的那些。
Mike Chan 和 B 团队
我们觉得自己将要改变世界,结果我们做到了。
—Mike Chan
在 1.0 版本之前加入系统团队的最后一位成员是 Mike Chan。
Mike 从中学开始就想成为一名程序员。当他看到游戏 Lode Runner 时,他就想长大后编写视频游戏。然而,这个梦想并没有持续多久;在高中时,他更感兴趣的是计算机系统的管理。但在大学时,他上了编程课,重新回到了成为程序员的初衷。他毕业后找到的第一份工作是在 Google,这决定了他的命运。
他在 2006 年加入了 Google,加入了 San 和 Rebecca 所在的平台团队。像他们一样,他也最终转入了 Android 团队,并在 2008 年 2 月,Rebecca 后一个月到达。SDK 已经发布,但仍有很多工作要做,才能将产品推向 1.0 版本。
安全保护
Mike 的启动项目是在发布 1.0 版本之前使 Android 变得安全。没有压力。
Android 从一开始就考虑了安全性。Swetland 特别希望为 Android 实现一个比他在 Danger 工作时使用的更安全的模型。那些 Hiptop 设备的资源更加紧张,并且没有硬件设施来保护应用程序之间的安全,所以它们依赖软件机制。Brian 坚持要求所有 Android 硬件必须具备 MMU^(30),以提供硬件安全保护。
平台上安全的另一个重要方面是将所有应用程序视为设备上的独立“用户”。在其他操作系统中,用户之间会相互保护,但不会保护自己。所以,例如,你可以在 PC 上创建一个用户账户,且你在该账户中创建的数据会受到系统中其他用户的保护。然而,任何你安装的应用程序都会以你本人身份运行,因此所有的应用程序都可以访问你账户中的所有数据。用户与其安装的所有应用程序之间存在隐性信任。
但是,Android 工程师认为(这完全正确)设备上的应用程序不应当天生就值得信任。因此,Brian 的设计让每个应用程序作为设备上的独立、唯一的用户来运行,而不是以安装该应用程序的用户身份运行。这种方法通过 Linux 内核机制中的用户 ID(UID)保证了应用程序无法自动访问同一设备上任何其他应用程序的数据,即使这些应用程序是由同一设备所有者安装的。Brian 提供了一个低级服务来创建、销毁或以某个用户身份运行应用程序。框架团队的 Dianne Hackborn 将此服务与更高层次的应用程序权限集成,并构建了应用程序 UID 管理的策略。
这种硬件保护的进程和将应用程序视为用户的系统大致已经设置并运行,但还有许多细节需要打磨。例如,虽然应用程序进程相互之间是受保护的,但许多内置系统进程是以具有提升权限的用户身份运行,这使得它们能访问设备上超出其严格需要的数据。
与此同时,iPhone 最近被越狱过^(31),这成为了一个很好的提醒,促使他们在发布 1.0 之前完成这项安全工作。
迈克认为这个项目不仅是学习安卓操作系统和安全模型的绝佳入门,更是对斯韦特兰管理风格的初步了解,“布赖恩有一种有趣的方式,把你直接扔进深水区,看你能否自救。”
作为入门项目来说,这个算是……一个大项目。不仅有压力要完成,因为显然必须在发布第一个设备之前完成,而且这件事影响到当时在安卓平台上构建平台和应用的所有其他团队。压力山大。“当我试图做出改变时,我左冲右突,搞得一团糟。所有团队都在抱怨某些东西坏了,而我在尽快修复这些问题,尽量预见到它们。”
“当时的安卓工程总监史蒂夫·霍罗威茨一直在盯着我。‘你把构建弄坏了!’我说,‘我知道,史蒂夫,我知道我把构建弄坏了,我正在修复它。你站在那里并不会让我修得更快。’”
“那简直是一次火中取栗。学了很多东西,涉及了系统的各个部分,最后把所有东西都弄坏了。”
迈克的下一个项目是提高电池寿命。当时,在 G1 发布之前,电池寿命非常糟糕。更糟糕的是,所有团队都在互相指责这个问题。“应用团队会怪框架团队,框架团队会怪系统团队,系统团队则会怪应用团队。”
安迪并不在乎是谁的错,他只是希望问题能尽快解决。他把问题交给了斯韦特兰,斯韦特兰又把问题交给了迈克。
布赖恩问道:“你对电源管理了解多少?”
迈克说:“布赖恩,我什么都不知道。”
“那么,我建议你开始学习,因为你现在负责这个事情了。”
迈克很快意识到问题的一部分在于预期。“我跟大家解释的问题是:你们告诉我,我们的电池寿命必须和 iPhone 一样好。我们有能力在后台运行所有这些应用,^(32)我们的硬件有更大的屏幕,我们运行后台任务,我们是第一个支持 3G 的,而且我们的电池物理上更小。”
迈克做的其中一项主要工作是向系统中添加仪表,以了解电源的去向。在此之前,他们能看到电池在消耗,但不知道是谁在做什么,所以很难找到并修复根本问题。一旦他们知道了问题所在,就可以去解决它们。
Mike 还与框架团队的 Dianne 进行了持续的辩论。许多电池问题源自应用程序中的不良行为,比如长时间持有唤醒锁^(33),但用户通常会归咎于 Android。“我一直在推动一种更明确的系统,如果一个应用进入后台,系统就强制释放资源。也就是说,平台的灵活性减少了。Dianne 坚信这不是平台的问题,而是开发者的问题,正确的解决方案是教育所有这些应用开发者。”
“这是我们争论了多年的问题。”
Mike 参与的另一个项目是调速器。
操作系统中的调速器(governor)是通过改变 CPU 的速度或频率来节省电力的机制。例如,如果 CPU 运行得非常快,它会消耗更多的电力,从而消耗更多的电池。但是如果设备此时处于空闲状态,这就是一种巨大的不必要的电池浪费。调速器的作用就是检测这些不同的运行模式,并相应地调整 CPU 的频率。
当 G1 发布时,唯一有效的调速器是ondemand调速器,它是核心 Linux 的一部分。这是一个简单的系统,只有两种设置:全速和空闲。这总比什么都没有要好,但对于 Android 来说还不够,特别是因为该调速器的启发式设置是为 Linux 在服务器或桌面计算机上运行时调优的,而不是为移动设备这个受限的环境设计的。
Mike 在 1.0 的后期开始玩调速器,但在 Andy 向 Google 高层展示演示的过程中发生了不幸事件后,他不得不将这个项目搁置一旁。
Mike 提交了一个更改,不小心使手机变得非常缓慢。“我在 master 版本上实验了保守型调速器,这种调速器极度倾向于通过牺牲性能来节省电力,结果手机几乎无法使用。”
与此同时,Andy 和 Larry、Sergey 进行了月度回顾,向他们展示了该项目的进展。Andy 将一个 master 版本的构建刷入手机,然后去参加他的会议。
在会议上,他展示了使用该版本的演示,但…并不顺利。
“他回来了,气得不行。”
这次事件对 Mike 来说是一个很好的学习经验。一方面,他学会了在将更改推送给可能使用该构建的每个人之前,必须先进行测试。但另一方面,他也意识到拥有一个支持自己的经理是多么重要。
“Brian 在走廊上和 Andy 面对面争吵,喊着说使用 master 版本没有经过任何测试是他的错。我们做这些工作是为了按时推出 Android,我们没有时间确保你的演示完美无缺。我从没见过有人对 Andy 大声吼叫过,他从未提到我的名字,他知道这是我的代码。”
“他后来回到我的桌前,平静地告诉我撤回所有更改,并且在我们发布之后才去处理这个问题。”
B 团队
Mike 加入了 Rebecca 的 Droid 项目。系统团队在致力于 Passion(后来的 Nexus One)和 Droid 的人员之间进行了分工。Swetland 回忆道:“我当时决定,我们需要把系统小组分成两个团队,将工作分配到 N1 和 Droid 之间,并在团队会议上说,‘我们需要像 A 队和——’。在我还没来得及完善这个说法时,Erik^(36)接过话说‘B 队!’,令我震惊的是,他们居然把这个作为了荣誉徽章(可能也是因为它让我感到尴尬)。”参与 Passion 项目的人大多对该硬件更为熟悉。但 Rebecca 开玩笑说,Droid 项目有“B 队”,因为他们在做一个团队不太感兴趣的设备。Passion 当时得到了团队的所有喜爱和,嗯,激情。
Mike 说道:“每个人都认为 Nexus 会是那个将要推出的超级手机:第一款 Google 品牌的手机,没有键盘,设计非常流畅,采用 OLED 屏幕。这是一款很棒的手机。”
与此同时,Droid 硬件设计当时让人失望。“一直都在炒作设计会非常棒。当他们最终揭开设计的面纱时,它是一个丑陋的方形东西。我记得我当时想,这只是初步的原型吧。之后会有一个新的版本,带着最终的设计吧?不,这是我们要出货的设计。”
最终,Verizon 对 Droid 的品牌宣传和市场营销远远超过了 Google 对 Nexus One 的任何投入。更多内容见第四十五章(“Droid 做到了”)。
构建一个稳健的系统
在继续处理其余的软件堆栈之前,值得反思一下系统团队的做法和成就。首先,他们所构建的一切对于操作系统能够启动,更不用说正常运行,都是至关重要的。此外,他们处理工作的方式也体现了 Android 的一个总体主题,即完成一项完整(即便是快速完成)的工作,不仅满足当时的需求,而且展望未来,期待 Android 最终会变成什么样子(或者说是他们所希望的样子)。
例如,他们不仅仅是关注当前在开发中的一两款设备。在 Android 的其他团队专注于开发 Sooner 和 Dream 手机,准备 1.0 版本之前的工作时,系统团队则在让 Android 适配完全不同的设备,使其在未来的制造商世界中更加稳健和灵活,能够应对完全不同的硬件。
此外,团队不仅仅是将硬件厂商的驱动程序拼接在一起并交付结果;他们从零开始编写了一切,确保其稳定和稳健。
Nick 谈到团队中的这种动态:“为什么系统团队不是一个集成团队呢?集成更像是把各个部分连接起来让它们工作,从硬件厂商那里拿到驱动程序并让 Android 在这些硬件上运行,而不是自己写驱动程序。”

Android 移植到这款诺基亚设备上被斯韦特兰称为“假期移植”,它发生在 2007 年的感恩节周末。(图片由布赖恩·斯韦特兰提供。)
“我们当时写了一大堆设备驱动程序,很多其他公司是不会写这些的;他们只是会拿取硅芯片提供商交付的参考 Linux 驱动程序。那时候,参考 Linux 驱动程序真是糟透了。一个关键的决策就是我们决定不只是接受那些参考驱动,而是要重写它们,使其达到一个可以上传并且我们可以支持、维护的质量。其余的生态系统可以跟随我们的领导,分叉我们的驱动程序,或者直接重用它们。”

2008 年 3 月,Android 移植到 PC 上。横屏笔记本电脑屏幕并不能很好地展示竖屏模式的手机屏幕。(图片由布赖恩·斯韦特兰提供。)
“我们最终得到了质量更高的驱动程序。当然,我们也有一些 bug,但最终我们达到了稳定性。如果你有糟糕的驱动程序,它会让你失去稳定性——外设会随机失败,设备会重启。而且没有好的驱动程序、没有唤醒锁和类似的东西,很难正确地做电源管理;你就会把电池寿命摧毁。”
“这是我认为布赖恩在很大程度上负责的一个关键决策,它使我们走上了正确的道路。我们在这里构建一个高质量的代码库,做事的方式也是正确的。”
第八章:Java

我们从圣诞假期回来。我很早就到达,精神焕发,与 Rubin 交谈。他告诉我,他和 Brian 在假期期间共进晚餐,并决定我们将使用 Java 来编写所有内容。
—乔·奥诺拉托
语言选择
选择一个编程语言来开发 Android,可能比表面看起来更紧密地与 Android 的成长有关。毕竟,编程语言只是向计算机输入信息的媒介:这真的那么重要吗?
是的,的确如此。经验丰富的程序员可以并且确实会不断学习新语言。但即使是这些专家,也会形成一些模式,使得他们在熟悉的语言上更加高效。而中间件的效果,或者开发者可以在项目间迁移的工具库,也是不可忽视的。一个程序员可以在一个项目中依赖某些库^(1),然后在其他项目中继续使用它,这意味着他们在每个新项目中都能更加高效和富有生产力,因为他们无需重新发明轮子。
选择使用 Java 编程语言^(2)是一个重要决策,因为在 Android 发布时,Java 是全球软件开发者广泛使用的主要语言之一。Android 允许这些开发者利用他们现有的语言技能来开发应用,这意味着许多开发者可以避免学习新语言所需的上手时间。
但在 Android 早期,这个语言选择并不是显而易见的,也没有立即确定。实际上,内部讨论了三种语言。
首先是 JavaScript。事实上,最初只有JavaScript,因为 Android 最初是一个基于网络编程语言编写的桌面应用。
JavaScript 是开发者用来编写网页代码的编程语言。当我们在浏览器页面上看到某些动画时,这些动画通常是由 JavaScript 代码驱动的。但 JavaScript 作为一种编程语言,稍显凌乱。对于开发者来说,使用 JavaScript 让东西基本上能工作很容易,但它的一些基本概念^(3)使得编写大型系统变得更加困难。
在 Android 的真实平台开发开始后,选择使用哪种语言成为了一个问题:JavaScript、C++,还是 Java。
C++ 很有吸引力,因为许多开发者熟悉它,并且它至今仍用于低级编程任务。C++ 开发者对应用程序操作的许多重要方面拥有很大的控制权,例如内存分配。但另一方面,开发者必须在应用程序中管理这些信息。如果他们分配了内存来存储一个对象(比如图像),他们必须确保在使用完后释放内存。不这样做(这是软件中非常常见的问题)可能会导致 内存 泄漏,即内存被不断浪费,应用程序会无限膨胀,直到耗尽系统中可用的所有内存,最终由于系统没有更多内存可用而崩溃。
Java 是一种围绕 运行时 或 虚拟机 (VM) 概念构建的编程语言,它处理所有 C++ 程序员必须自行处理的内存管理琐事。在上面的图像示例中,Java 程序员只需加载图像,这样内存就会被分配。当图像不再被使用时,运行时会自动 回收 这些内存,这被称为 垃圾回收。Java 开发者可以忽略内存回收(和内存泄漏)的细节,专心编写实际的应用逻辑。
团队考虑选择 Java 的另一个原因是 J2ME^(4) 的存在,这是一个基于 Java 的平台,已经能够在各种设备上运行。Ficus Kirkpatrick 说:“当时,要在手机上运行并获得这些运营商的合作,你必须支持 J2ME。” 选择 Java 提供了一定的能力在平台上运行 J2ME 代码,而这一点在 Android 最初创建时被认为是有用的。
最终,强大的 Java 代码编写工具,包括 Eclipse 和 NetBeans,都是免费的。而 C++ 则没有很好的免费 IDE^(5) 支持。微软提供了 VisualStudio,这是一个非常适合 C++ 开发的工具,但它并不是免费的,而 Android 想要吸引所有开发者,而不要求使用昂贵的工具。
最初的计划并不是只选择一种语言,而是提供多种选择。再次引用 Ficus:“我们最初的想法是要以语言无关的方式做一切。你可以用 JavaScript、C++ 和 Java 编写应用程序。最终我们意识到,只有我们十二个人,根本做不到这一点。所以我们决定‘好吧,我们必须选一种语言。’”
Andy Rubin 认为只选择一种语言是对开发者的简化。Swetland 说:“我们曾考虑过同时使用 Java 和 C++。Andy 强烈认为我们需要一种语言,一种 API,这样就不会让事情变得复杂。他认为 Symbian^(6) 以及他们的 n 种不同工具包^(7)会让人感到困惑。”
这些是参与辩论的技术细节和优点。实际的决定过程则没有那么正式;是安迪做出了决定,并在某个晚餐时告诉了斯威特兰德。
语言选择很好地展示了 Android 决策的快速性。部分原因是因为这是安迪的决定,而安迪往往做出艰难的决定,然后组织会匆忙执行。但更重要的是,决策迅速做出,以便组织可以继续前进,做剩下的无限多需要做的事情。语言选择曾在内部讨论了一段时间,没有正确答案,但拥有一个决策,比每个人都对那个决定感到满意更为重要。所以,选择了 Java,团队也继续前行。
费库斯谈到这个决定时说:“考虑到运营商希望支持 J2ME^(8)应用,并且当时存在这种生态系统,实际上这并不算是一个真正的选择。而且我们中的一些人曾在 Danger 工作过,做过 Hiptop,我们知道我们可以让 Java 在低端设备上运行。”
黛安·哈克博恩回忆起这个决定时说:“安迪非常正确地说,‘我们不能使用三种不同的语言,那太荒谬了,我们需要选一种。我们就选 Java 吧。’那时关于这个决定有很多戏剧性的争论。没有人关心 JavaScript,但很多人关心 C++。”
选择 Java 是有多方面原因的,其中包括团队的专业能力。例如,来自 Danger 的工程师们曾学会了如何用 Java 为那些早期极其受限的设备高效地编写操作系统。最终,对于这一决定以及其他许多决策,团队采取了务实的态度。正如黛安所说:“不是因为有人特别喜欢它,而是因为它是实现平台成功的合理选择,然后团队进行调整。”
虽然 Java 被选为 Android 开发的主要语言,但事实上(并且现在仍然是)很多 Android 代码是用其他语言编写的。平台本身的大部分是用 C++编写的(甚至有一些部分使用汇编语言)。此外,大多数游戏都是用 C++编写的,其他一些应用也是用 C++编写的,完全或部分如此。C++是一种受开发者欢迎的语言,因为它为低级代码提供了一些性能优势,并且能够与现有的 C++库和工具进行集成。但主要的语言,尤其是对于大多数非游戏应用来说,变成了 Java,这也是所有 Android API 所用的语言。
并不是每个人都对语言的选择感到满意。San Mehat 并不是 Java 的忠实粉丝,尤其是在他从事低级系统编程时。“我对语言本身没有问题。嗯,可能有,因为它隐藏了许多写出高效、可扩展代码时重要的细节。”他为自己的车订了一块新车牌,写着 JAVA SUX。“当你去申请车牌时,车管局会问你那是什么意思。我说我以前在 Sun 工作,我们做了这个 Java 东西,它代表着‘Secondary User Extensions’,他们就说‘好的’。”

San 的车牌。San 并不喜欢 Android 的语言选择。(图片由 Eric Fischer 提供。)
运行时
要理解运行时,你需要对编程语言有一些了解。程序员使用他们选择的任何语言编写代码(C、Java、C++、Kotlin、Python、汇编语言……随便什么)。计算机并不能理解这些语言,它们只理解二进制代码(0 和 1)……就这么简单。二进制代码表示计算机执行的指令,比如“将这两个数字相加”。为了将典型的编程语言转换为计算机能够理解的二进制编码指令,程序员使用一种叫做编译器的工具。
编译器将程序员使用的任何语言翻译成计算机理解的二进制指令。例如,你可以将一段用 C 语言编写的代码编译成 PC 可执行的二进制表示,使得编译后的 C 代码能够在该 PC 上运行。
然而,这段编译过的代码可能无法在其他类型的计算机上运行,比如 Mac 或 Linux 服务器,因为其他计算机可能没有相同的 CPU,因此编译器生成的二进制指令在这些系统上无法理解。相反,原始源代码需要针对你希望运行的每种硬件编译成不同的二进制版本。

单独的编译器为每种机器类型创建独特的可执行文件,用于运行代码。
然后出现了 Java。Java 编译器将源代码转换的不是机器可读的代码,而是一个叫做字节码的中间表示。这个字节码可以在任何安装了额外软件的计算机平台上执行,这个额外的软件就是运行时。运行时会解释字节码,并将其转换为该计算机的二进制表示,本质上是在运行时编译它。Java 能够在不同硬件上运行的能力就是 Sun Microsystems(詹姆斯·高斯林在创建 Java 时所在的公司)所说的“写一次,到处运行”。代码会被编译成字节码,然后可以在任何安装了 Java 运行时的目标计算机上运行。

Java 代码只需要编译一次。这将生成一个可以在所有目标机器上运行的单一可执行文件,只要该机器拥有 Java 运行时环境。
由于 Android 团队希望使用 Java,因此他们也需要一个运行时环境。事实上,他们经历了多个不同的运行时环境。
起初,团队仅仅使用了现有的运行时环境。其中第一个是 Waba。^(9) 后来,JamVM^(10) 虚拟机替代了 Waba。到这时,Mike Fleming 加入了团队,并帮助启动了 JamVM:“Dan Bornstein 的虚拟机还需要一段时间才能准备好,而我们将编写大量代码。如果我们要成为一个 Java 平台,就需要一个能够运行的东西,至少暂时能用。Swetland 和 Fadden 帮了我很多忙。” JamVM 一直被 Android 使用,直到 2007 年,Android 运行时(Dalvik)开始运行。
Dan Bornstein 和 Dalvik 运行时
打开一个文件,随意敲击几下键盘,然后调试直到完成。
—Dan Bornstein(根据 Andy McFadden 的说法)
尽管 Waba 和 JamVM 足以进行原型设计和早期开发,但团队希望拥有自己的运行时环境,能够根据需要进行控制和定制。Brian Swetland 参与了 Danger 编写的运行时环境,但他在 Android 的内核和系统工作上已经忙不过来了。因此,团队聘请了 Dan Bornstein,Brian 曾在 Danger 与他共事过。
Dan(团队称他为“danfuzz”)接手了来自 Brian 在 Danger 的运行时工作。“我被聘用后没多久,我开始称自己为‘Brian Jr.’他真的不喜欢这个名字……这也是我为什么一直这么叫的原因。”
Dan 七岁时开始接触编程。他和哥哥只是想玩视频游戏,于是他们最终说服父母购买了一台 Apple II,而父母认为这既是游戏机又是教育机器。显然父母赢了,因为 Dan 不仅仅玩游戏;他开始编写游戏:“我完全编写了些糟糕的电子游戏,大多数是文本和低分辨率图形。” Dan 和他的哥哥最终都成为了软件工程师。
Dan 在 90 年代和 2000 年代初期曾在硅谷的多家公司工作,包括 Danger,在那里他曾从事(等等……)Java 编程语言的运行时工作。因此,当他于 2005 年 10 月加入 Android 团队时,他是这项工作的自然人选。
Dan 的第一个任务是评估可能的选项。对于当时 Android 小团队来说,是否可以简单地使用现有的东西(无论是开源的,还是能够获取的技术),或者是否需要内部构建一些东西,并不明显。Dan 开始同时进行这两项工作,评估现有的运行时环境,同时也在从零开始构建一个运行时环境。
尽管 Waba 和 JamVM 非常适合快速使团队能够使用 Java,但它们并未被认真考虑为长期的解决方案。这两种运行时直接解释 Java 字节码。但团队认为,通过将 Java 代码转换为另一种更优的格式,可以获得性能和内存方面的提升。新的字节码格式意味着新的运行时环境,因此 Dan 开始了这项工作。
Dan 开始着手开发一个新的运行时环境,他将其命名为Dalvik:“我刚读完一本[《McSweeney’s》]的期刊,内容是现代冰岛小说的英文翻译。所以那时我脑子里一直想着冰岛。我查看了冰岛的地图,试图找到一个简短且易于发音的名称,并且没有任何奇怪的字符,最后我找到了 Dalvík^(11)(或者‘Dal-veek’,就是这样发音的)。它听起来像是一个不错的小镇。”

为 Android 编写的 Java 代码经过了两个编译步骤:一个是创建 Java 字节码,另一个是将其转换为 Dalvik 字节码,然后在 Android 的 Dalvik 运行时中运行。
Dalvik 虚拟机并不是直接运行 Java 字节码,而是运行另一种从 Java 字节码编译而来的字节码格式。采用自己特有的字节码格式在大小上可以获得效率提升,而当时设备上的存储空间非常紧张。Dalvik 字节码需要一个额外的编译步骤(使用另一个编译器,叫做 DX)才能转换为 Dalvik 可读取的格式,称为 dex^(12)。

Dan Bornstein,位于冰岛 Dalvík 镇外。在完成 G1 工作和设备实际发货之间的这段时间,Dan 从 Dalvik 的开发工作中休息,去了一趟 Dalvík。(照片由 Dan Bornstein 提供。)
最终,Fadden 也参与了运行时环境的开发。“Danfuzz 已经让字节码转换器运行得相当不错,他需要有人加入并编写虚拟机。我自愿参与,但指出我对 Java 和虚拟机了解甚少,也不太清楚从哪里开始。他说,‘打开一个文件,随便敲几下键盘,然后调试直到完成。’”
团队的另一位工程师 Dave Bort 编写了 Dalvik 垃圾回收器的第一个版本。这个垃圾回收器与 1.0 版本的运行时一起发布,并成为几年优化和改进的基础。
在这段时间里,运行时环境一直在不断变化,而所有为平台编写的 Java 代码都在适应这些变化。从 Waba 到 JamVM,再到初步的 Dalvik 运行时,发生了巨大的转变,但代码依然在运行。Romain Guy 评论道,即便团队在更改系统中一个巨大且关键的部分^(13),“我不记得曾遇到过致命的错误,甚至根本没有错误。我不记得 Android 的其他部分曾那么稳定过。”Dan 回答道,“这部分系统的本质在某种程度上有助于这个问题——如果虚拟机不工作,整个系统就会崩溃。”
胚胎(Zygote)
为了让 Android 在 1.0 版本上正常运行,Dalvik 团队创建了一项技术(直到现在依然在使用),它被称为 Zygote。^(14) Zygote 就像是你做三明治时用来切片的面包。你当然可以每次做三明治时从零开始烤面包,但那样会浪费很多时间和精力。显然,拥有一条可以随时切片的面包,更加快捷和方便,用来快速开始做三明治。Zygote 就像是应用程序的三明治面包。
Dan 有一个想法,这个想法来源于 Emacs^(15)(一款流行的 Unix 系统文本编辑器)的一个特性,它允许你随时保存当前状态,然后从这个保存的状态重新启动 Emacs(巧妙地称为undump)。这意味着 Emacs 可以更快启动,因为它只是从磁盘中加载状态,而不是在启动时执行一大堆代码逻辑。“我的想法是,我们实现一个类似 undumper 的系统,正如 Emacs 所做的那样,Mike [Fleming]说,‘我们能不能跳过将状态保存到磁盘然后重新加载的步骤?’然后他就开始着手实现了。”Mike 使这个系统成功运行,极大地改变了应用程序的启动方式。不同于每个应用程序加载它所需要的所有代码并在加载时初始化,Zygote 系统创建了一个单独的进程,包含了大部分核心平台代码,基本上是预加载并初始化了所有代码。每当一个应用程序启动时,Zygote 进程会被fork(复制成一个新的进程),从而几乎可以立即启动新应用程序的早期阶段。
Bob Lee(曾负责核心库开发,下一章将讨论的内容)谈到 Zygote 时说:“它简直太简单了!就像一个 API 调用!我们能够做到这一点的原因是内存采用了写时复制(copy-on-write)技术。^(16) 所以只要你不去触碰那些来自初始 Zygote 进程的内存页面,所有的内存就会在整个操作系统中共享。这个方法真是一个聪明、优美的解决方案,充分利用了已经存在的技术。”
该系统起初并没有按预期工作。Bob 追踪了垃圾回收器的问题:“经过一次垃圾回收后,我发现‘我的应用又占用了这么多内存!’这是因为垃圾回收器会触及每一页内存。”也就是说,运行时的正常操作会写入内存中的某些页面,而这些页面需要保持只读,以便 Zygote 的共享内存方法能够正常工作。
Fadden 提出了一个解决方案。每个新的进程会在 Zygote 阶段之后将堆与垃圾回收器分离,不再让垃圾回收器检查这些内存。共享内存部分在新应用程序中甚至不存在,因此不会被触及。
在此之后,Bob 和 Fadden 继续致力于 Zygote 的工作,找出哪些类^(17)需要驻留在 Zygote 中,以便从所有应用中获得最佳的共享效果。Bob 说:“我修改了虚拟机并添加了一些工具,能够记录每个类的初始化时间,找出每个类分配了多少内存,然后通过算法决定哪些类需要预加载。你不希望为那些只会被一个应用使用的共享进程占用过多内存。”
Bob 归功于 Zygote,让 Android 在那个时候能够正常运行:“Zygote 的出现帮了大忙,它使得共享内存成为可能,从仅运行几个 Java 进程到在一个非常小的设备上运行数十个进程。而且不再需要等待整个虚拟机启动,我们的应用实际上看起来更快;它们会瞬间启动,因为我们只需分叉一个进程并从那里开始。所有东西已经预热完毕。”最终,Zygote 不仅包含代码,还包括共享数据,如图像,并继续为 Android 提供内存和启动的好处,随着平台的增长,Zygote 的作用也日益重要。
第九章:核心库

为平台提供一种编程语言是一回事。这确实是个大事,特别是当它是大多数开发者已经熟悉的语言时。但程序员们也希望拥有标准的实用工具函数,这样他们就不需要每次编写应用程序时重新发明轮子。一种编程语言让你能够编码逻辑(如条件语句、循环、方程式)。但像数据结构、网络或文件读写这样的更高层次的功能,是核心库的职责。
尽管 Android 团队采用了 Java 语言,但他们明确没有使用与 Sun Microsystems 提供的 Java 版本(即 Java 开发工具包 JDK)一起发布的库实现。JDK 包含了比如 ArrayList 类,这个类实现了一种在编程中常见的简单数据结构。但是 Android 没有使用这些类,所以他们需要提供自己的实现。
Bob Lee 和 Java 库
当 Android 需要标准的 Java 库时,他们引入了一位在谷歌其他地方工作的 Java 专家:Bob Lee。
Bob(也被称为“疯狂的 Bob”^(2)) 在 90 年代初中时开始编程,主要是因为他想编写视频游戏。他很快掌握了多种编程语言,并在高中时从制作视频游戏转向为附近的一所大学建立网站。该大学对他的作品印象深刻,给了他全额奖学金让他继续从事这个工作。但大学不适合 Bob,他离开后开始做咨询工作,同时写书和流行的 Java 库,最终于 2004 年获得了谷歌的工作。
Bob 想要从事移动技术工作,因此在广告团队工作了几年后,他于 2007 年 3 月转到了 Android 团队。
当 Bob 加入时,Android 仍在使用 JamVM 运行时,直到 Dalvik 运行时上线。核心库基本上是一堆人为了单次使用目的编写的随机实用工具。“它们完全不兼容。某个人需要某个功能,就会实现自己需要的部分。它们看起来有点像 Java 库,但显然缺少了很多。”
幸运的是,已有一些现成的标准库选项,因此 Bob 和团队对它们进行了评估。“我们看过 GNU Classpath,但最后选择了 Apache Harmony^(3)。它有很多不太好的地方,所以我们需要重写其中的一部分,然后把它们贡献回去。比如我们重写了 ThreadLocal [和] Runtime.exec()。重写这些东西并合并回去是其中很重要的一部分。”
“还有一些由团队中的其他工程师添加到 Android 核心平台的 API,只是因为当时看起来是个好主意。如果有人认为某个功能可能有用,他们就会把它加进去。结果有一些真的很糟糕的东西。”
一个例子是WeakHashMap,这是一种开发人员在内存受限的情况下使用的数据结构类,就像当时的 Android 一样。它比传统的HashMap类更有优势,因为它会自动清理(垃圾回收)不再使用的对象。就像为内存堆清理垃圾的 Roomba,清理你遗留下来的垃圾。请注意,这里“弱”(weak)一词来源于“弱引用”这个术语,指的是当对象不再使用时,可以被垃圾回收的对象。
框架团队的 Joe Onorato 添加了WeakHashMap API。算是吧。他说:“我有一个库依赖于WeakHashMap,我需要将它链接^(4),所以我创建了一个名为WeakHashMap的类。”问题在于,Joe 的类并不是一个“弱”HashMap,它只是一个标准的HashMap。它继承了HashMap,但没有添加任何能让它变得“弱”的逻辑。稍后,框架团队的 Jeff Hamilton 正在编写需要WeakHashMap功能的代码。他发现这个类已经存在于核心库中,使用它时遇到了内存问题,进行了大量的调试,直到 Jeff 发现 Joe 的WeakHashMap类根本没有清理内存。它只是一个普通的HashMap,并没有执行 Jeff 预期的垃圾回收工作。
Bob 继续说道:“我知道 Android 的 API 本来可以做得更好……但它们也可能做得更糟。”Bob 的大部分时间都用来防止这些 API 公开。“我会找到并删除所有这些东西。如果有一个类只被一个应用使用,我会把它移回到那个应用中——如果你不打算在多个应用中使用它,它就不应该出现在框架库里。”
在使核心库正常工作的过程中,Bob 实现了重要的网络功能,并修复了其中的错误。一个问题导致每台手机根本无法启动。“第一次启动手机时,它必须连接到时间服务器,但设备的时间设置在 2004 年某个时候。”手机会尝试通过安全连接连接到服务器,这需要服务器上的安全证书。但是手机上的初始时间早于证书在服务器上发布的时间,因此连接会失败,手机无法启动。Bob 的解决方案是捕获这个失败条件,并将手机上的初始时间设置为他修复这个 bug 的那一天。
Bob 还解决了一个仅在移动数据下出现的网络问题。Android 手机出现了严重的断网问题,看起来像是运营商网络基础设施的问题。
网络协议内置了容错机制,因为网络可能会中断,或者数据包可能会丢失或延迟。Android 使用了 Linux 中的拥塞窗口方法,该方法通过将数据包大小减半,然后再减半,一次次减小,直到从服务器获得数据包通过的响应。然后,它会在每次成功后将数据包大小翻倍,直到数据包最终恢复到原始大小。
这个算法对于常规的互联网流量是合理的,在互联网中,延迟(发送消息和接收响应之间的延迟)通常以毫秒为单位衡量,且中断比较少见。但它对蜂窝数据并不适用,因为蜂窝网络常常有一秒或更长时间的高延迟,而且短暂的中断也很常见。鲍勃进行了一些性能分析和调查,找到了问题所在。在故障发生后,数据包大小减少了,“每当数据包成功传输时,它会将缓冲区大小翻倍。但在移动网络上,由于延迟较高,2.5G 或 3G 网络的往返时间会达到一到两秒。所以,它只是每次成功往返时才增大缓冲区大小。在你遇到某种中断后,重新调整缓冲区大小可能需要大约 30 秒。”
杰西·威尔逊与糟糕的 API
我们花了很长时间将这些 API 从头重新实现,以使它们变得更加优秀,同时保持它们原本糟糕的 API。
—杰西·威尔逊
鲍勃曾一度独自工作于核心库,但最终,在 1.0 版本发布后,他得到了帮助。乔希·布洛赫(Josh Bloch)在 2008 年底加入了他的团队,杰西·威尔逊则在 2009 年初加入。
杰西·威尔逊(Jesse Wilson)在鲍勃(Bob)加入 Android 之前一直在与他一起工作于 Google AdWords 产品。“当 Android 看起来不像是一个负责任的职业选择时,鲍勃从 AdWords 转去 Android。我跟随他去那里,更多的是为了和鲍勃一起工作,而不是为了做 Android。”
最终,鲍勃和杰西离开了 Android 和 Google。鲍勃成为了 Square 的首席技术官(CTO)。杰西再次跟随鲍勃,加入了 Square。^(6) “我想他掌握了我的把柄。”
Jesse 描述了核心库团队的工作:“在 Android 的第一年,大家只是带进来他们认为需要的库,并把它们放到公共 API 中。我们有一个叫做 kXML 的东西,它是一个拉取解析器。我们有 org.json JSON 库。还有 ApacheHttp 客户端。我们基本上拥有这些库的 2006 年版本快照,它们后来加入了成千上万的特性,使它们变得过于庞大,无法适应 Android。它们的当前版本在许多重大方面不兼容。如果你在发布一个 Web 服务器,你可以控制你包含的版本;如果你做了不兼容的更改,客户端只需要做相应的修改。Android 的版本控制方式是,如果我们改变了一个 API,比如 JSON 库中的 API,即使新的 API 更好,应用也不能选择是否使用这个更改,所以必须确保 100% 向后兼容。因此,我们花了很长时间将这些 API 重新实现一遍,既要保证它们更好,又要保持现有的糟糕 API。”
“我们继承了所有的 Apache Harmony 代码,而 Apache Harmony 从来都不是一个真正发布的产品。它更多的是一个可以用来构建发布产品的清单。将一些半成品的东西做成正确的,花费了很多工作。”
“这其实是大量的重新实现和优化。标准库中的 org.json 代码,100% 是全新的。一天,Dan Morrill 找到我,说,‘嘿,提醒一下,我们正在使用的 JSON 库的开源库中有一个条款,‘软件应仅用于善良的目的,不得用于邪恶’^(7)。这意味着它不是开源的,因为开源没有针对任何目的的歧视。’所以我得去重新实现它。”
第十章:基础设施

在任何软件项目中,尤其是当项目不止一个或两个人在合作时,一个不太明显的部分就是实际构建产品所需要的基础设施。基础设施可能涉及多个方面,包括:
-
构建 你如何将随机工程师不断提交的代码构建成产品?如果产品需要在多种不同的设备上运行,而不仅仅是一个设备,怎么办?你将如何存储这些构建文件以便进行测试、调试和发布?
-
测试 一旦产品构建完成,你如何进行测试?你如何进行持续测试,以便在问题变得严重之前抓住潜在的错误(并且在出现问题时,可以更容易追溯到错误最初被提交的时刻,进而定位和修复)?
-
源代码控制 你将所有代码存储在哪里?如何让一个团队的成员同时修改相同的源代码文件?
-
发布 你如何将产品实际发布到需要它的设备上?
Android 需要专门的人来解决这些基础设施问题。
乔·奥诺拉托和构建
在最初的阶段,Android 的构建是由一个脆弱且耗时的系统拼凑起来的,这个系统为内核、平台、应用以及其他所有部分构建了组件。在早期,构建的内容并不复杂,系统能够满足需求,但随着 Android 的规模扩大,原有的系统已经无法再适用了。因此,在 2006 年春天,乔·奥诺拉托开始着手解决这个问题。
乔认为自己注定要成为程序员,因为他的父母都是麻省理工学院的毕业生。“他们在技术模型铁路俱乐部相遇;^(1) 一见钟情。几乎可以预见我会成为一名计算机科学家。”
在高中时,乔与他的朋友 Jeff Hamilton(未来的 Be、PalmSource 和 Android 同事)一起参与了年鉴的制作,制作了第一本完全数字化的 Jostens^(2)年鉴。他们的系统包括一个定制的搜索算法和一个数字化系统,这些都简化了出版过程并降低了学生的成本。乔后来(再次与 Jeff 一起)在 Be 公司和 PalmSource 公司从事类似的操作系统项目,这些项目与他后来在 Android 所从事的工作非常相似。
2005 年末,乔对 PalmSource 的未来方向感到不满,因此他联系了曾在 Be 公司共事的前同事。那人认识 Swetland,并把乔推荐到了 Android 团队。乔收到了一份邀请,但不确定自己加入的是什么团队,因此招聘人员把他介绍给了 Andy。在得到保密承诺后,Andy 告诉乔:“我们将打造最棒的手机。” 就这样,乔加入了 Android 团队。
乔在早期参与了多个项目,包括框架和 UI 工具包。但是在 2006 年春天,他发现构建系统需要进行大规模重构。
“我们有一个很大的递归^(3)make 构建系统,我当时想,‘我们该有一个真正的构建系统了。’这有点有争议:这甚至可能吗?”幸运的是,Joe 有 Be 公司的经验。Be 使用了一个类似的构建系统,那个系统是由一群人编写的,其中包括未来的 Android 工程师 Jean-Baptiste Quéru(团队称他为“JBQ”)。Joe 回忆道,“我想一些危险公司的人[他们也曾在 Be 工作]在那之前就离开了,认为这是不可能完成的事。怎么可能有一个 make 文件知道所有的事情?它会搞得一团糟。但...它成功了。”
Joe 深入工作,成功让 Android 的构建系统运作起来,在这个过程中加速了构建并增强了系统的稳定性。整个项目持续了几个月,最终形成了一个名为“总依赖感知”的系统。
Ed Heyl 和 Android 基础设施
第一个猴子实验室是我的笔记本电脑和七台 Dream 设备。我写了一些脚本和工具,把它们弄得崩溃。
——Ed Heyl
Joe 编写的构建系统在一段时间内运作得足够好。但随着团队的扩大和代码提交数量的增多,出现了一个需求:一个能够在开发者提交更改时自动构建产品的系统。例如,如果有人提交的代码导致了一个 bug,最好能仅凭这次更改就构建并测试产品,而不是等到其他多个更改叠加后才进行构建和测试,这样会掩盖问题的根本原因。
在 2007 年 9 月,为了控制构建和测试基础设施,团队引入了当时在微软工作的 Ed Heyl。
Ed 在大学学习计算机科学,但迫不及待想毕业。“我想尽快毕业进入职场。我在学校表现还可以…但在工作中我表现得更好。”
Ed 于 1987 年加入了苹果公司,并在那里工作了五年。“那时公司处于一个非常奇怪的状态。他们仍然靠 Apple II 赚钱,但所有的关注都集中在 Mac 上。”几年后,Ed 加入了 Taligent^(4)的分拆公司,随后不久加入了 General Magic,“正好在他们进行 IPO 的时候。它创下了 IPO 增幅的记录,但在之后几个月股价暴跌。公司当时状况并不健康,所有人都有些失望。IPO 前的炒作太过火了,之后的落差很大。”
Ed 在 General Magic 工作了大约十个月,然后加入了 WebTV。他一直待到微软收购,并在微软继续工作了十年,直到加入 Android 团队。在 WebTV 和微软,Ed 与未来的 Android 团队成员合作,包括 Andy Rubin、Steve Horowitz、Mike Cleron 和 Andy McFadden。
Ed 在 2007 年 10 月 Android SDK 首次发布时加入了 Android 团队。Ed 加入时,Android 已经有了一个名为Launch Control的自动化构建系统。每天三次,它会接收所有提交的代码并进行构建,生成的结果随后可供自动化测试系统使用。
Launch Control 比什么都没有好,但远远不足以满足 Android 的需求。“它只是供 QA 测试使用,而不是一个展示系统状态的仪表盘。它缺乏追溯性。持续集成^(5)尽可能多地构建和测试,以提供尽可能多的数据点。”
团队需要一个可以更频繁地构建和测试的系统。这个系统还需要具备可扩展性。当时,它只为一个设备构建:Sooner。但不久后,团队将拥有 Dream 设备(该设备与 1.0 一起发布,成为 G1),系统必须能够为多个目标构建。
Ed 最初是独自开始工作的,但最终他领导了一个团队,专注于构建工作。Ed 说:“是 Dave Bort 接手了这个工作,并真正把它做得足够好,可以用于产品开发。让它变得非常稳固,设计合理,工作方式布局清晰。Dave Bort 将它从一个不错但有些粗糙的构建系统,做成了一个产品。”
“在重新组织构建系统的同时,他也重新组织了整个源代码树。他为开源和架构级的事情奠定了所有基础。尽管他主要在构建系统上工作,但它是架构性的;这种变化影响了整个系统。他为此奠定了所有基础。可以说,他让 Android 准备好了开源。”
测试,测试
另一个需要解决的问题是测试。如何验证不断从不同工程师在系统不同部分提交的随机软件片段不会破坏系统?在任何软件系统中,都需要有某种自动化测试框架^(6),以便快速捕捉问题。那时,Android 并没有自动化测试系统,于是 Ed 让一些 monkeys 来完成这项工作。
“在 WebTV 时,我们有一个叫做 monkey 的东西^(7),它会在网页上找到链接,然后疯狂地到处冲浪。”
“我记不清楚 Dianne 是否已经为 Android 平台做过这件事,还是我们在与她讨论时她做了这件事。但她将随机化和事件注入的系统集成到了框架中,今天我们称之为‘monkey’。”
“我建立了第一个猴子实验室,它就是我的笔记本电脑和七台 Dream 设备。我编写了一些脚本和工具,让它们不停地崩溃,抓取崩溃的[报告],然后让它们重新工作。我会分析这些报告并总结出来。这样每天我们就可以知道它能够处理的事件数量以及遇到的崩溃情况。我和 Jason Parks,以及最终的 Evan Millar,连接了一套工具来帮助创建我们的第一个稳定性数据。那套系统坚持了很多年,尽管它很糟糕。它只是一些 Python^(8)脚本,用来分析错误报告并输出 HTML 报告。2008 年末,我雇佣了来自微软的 Bruce Gay。他接手后把这些变成了一个真正的实验室环境。”^(9)
Bruce 在这些年中把实验室从最初的七台设备扩展到超过 400 台。他提到,在这个过程中有一些预料之外的问题需要解决。“有一天我走进猴子实验室,听到一个声音说,‘911——发生了什么紧急情况?’” 这个情况促使 Dianne 在 API 中添加了一个新功能,isUserAMonkey(),它用来限制猴子在测试过程中不应该执行的操作(包括拨打电话和重置设备)。
早期的猴子测试在崩溃之前会运行最多 3,000 个输入事件。到 1.0 版本时,这个数字已经达到约 5,000。Bruce 说,“‘通过’的标准是 125K 个事件。我们花了几年才达到这个目标。”

2009 年 5 月的猴子测试实验室(照片由 Brian Swetland 提供)
Romain Guy 谈到猴子测试在 1.0 版本发布前的重要性。“那时候我们非常依赖猴子测试。每天晚上我们都会跑这些猴子测试,每天早上我们都会有很多崩溃需要修复。我们的目标是提高猴子的测试数量;我们能让猴子在不崩溃的情况下运行多久?因为崩溃无处不在,从小部件到内核再到 SurfaceFlinger^(10),尤其是我们切换到触摸屏后,情况变得更加复杂。”
除了猴子测试,团队中的其他成员也在进行不同类型的测试,以验证平台的正确行为。Evan Millar 在 2007 年初从研究生院加入团队,他负责早期的性能测试框架,测量应用程序启动所需的时间。他还参与了早期的自动化测试系统——Puppet Master,它允许测试脚本驱动 UI(打开窗口、点击按钮),并与黄金图像进行正确性比对^(11)。由于比较黄金图像的困难,加上测试和平台的异步性,结果是喜忧参半的。测试脚本会请求特定的 UI 操作,比如点击一个按钮或启动一个应用程序,但平台处理该事件可能需要一段时间,这使得正确性测试变得复杂且容易出错。
Chiu-Ki Chan 在加入地图团队后,曾在服务和 Android Market 团队工作,处理了一些这些内在的测试困难。她一直在开发一个系统来自动化地图应用的测试,但越来越对在一个并非为测试设计的系统上测试她的应用感到沮丧。她说:“测试?根本没有所谓的测试。”
Android 测试的一个重要部分是兼容性测试套件(CTS)。这个系统最初由外部承包商构建(由 Patrick Brady^(12)) 管理)。CTS 测试非常重要,因为它们不仅测试系统中特定功能块,并在测试失败时捕捉回归^(13),而且它们也是合作伙伴通过认证所必需的,确保他们发布的 Android 设备符合 Android 定义的平台行为。例如,如果有一个测试将屏幕变成白色,并测试结果是否确实是白色像素,那么设备不应该将“白色”误解为红色并且仍然通过该测试。
精益基础设施
Android 构建、测试和发布基础设施,像 Android 的其他部分一样,最初是由一个资源有限的小团队创建的。这是关于如何在有限预算内做出投资的一个有意识的决策,考虑到产品尽快发布的优先级。Ed Heyl 说:“我们根本不知道我们正在做的事情是否会成功。我们只是尽力制造一款新设备并让它有影响力。苹果已经占据了所有的市场关注,微软不打算放手,他们在那个时刻处于最佳位置。所以我们的一切思维方式都是:我们能做的任何事情,只为向前推进。我们没有优先考虑投资很好的解决方案,只是‘我们得让这个开始,证明我们能交付并持续迭代。’我们从未停下来想,我们真的需要投资建立一个构建基础设施,Python 脚本无法带我们走得太远,所以我们应该认真思考如何使用 Google 的后台基础设施。我们从未停下来想过这个问题。我们只是全速前进。”
“如果它是核心产品的一部分,我们会投入更多资源。但如果它只是测试或构建,那就只做最低限度的工作来让它启动。我们就是这么操作的。”
第十一章:图形

当 Android 团队的人说“图形”时,他们可能指的是完全不同的内容,因为图形功能有很多层次,这些功能由不同的团队实现,目的也各不相同。例如,有使用 OpenGL ES 的 3D 图形系统^1,以及最近的 Vulkan,支持从游戏到地图应用、虚拟现实和增强现实等各种应用。还有 UI 工具包中的图形功能,负责绘制文本、形状、线条和图像等内容,以便应用开发者能够用图形填充他们的用户界面。然后就是系统中最低层的图形功能,它提供了像素和窗口显示在屏幕上的基本能力。
我们将从图形的最低层开始,这一层是通过 Mathias Agopian 的工作而实现的,他是从 Be 和 PalmSource 招募的另一位成员,于 2006 年底加入 Android 团队。

一个极度简化的 Android 图形系统视图。应用程序调用 Canvas API 来绘制内容。Canvas API 由 Skia 渲染引擎实现,将形状和文本等转化为像素。SurfaceFlinger 提供了一个缓冲区或表面,像素被绘制到其中。SurfaceFlinger 调用 OpenGL ES,这是一个低级图形 API,用于渲染三角形。OpenGL ES 使用 PixelFlinger 来绘制缓冲区:注意,当 GPU(图形处理单元)成为智能手机的标准配置后,PixelFlinger 最终被 GPU 替代。最后,所有需要显示在屏幕上的表面(包括前景应用程序以及状态栏和导航栏)都在硬件合成器中合成,然后显示在屏幕上供用户查看。
Mathias Agopian 和 Android 图形
在我看来,软件渲染注定会消亡。
—Mathias Agopian
Mathias 是一个冷静、安静的人,他总是很晚到办公室,工作到很晚,几乎完全专注于编码(尽量避免电子邮件和会议)。
在早期,Mathias 有时会显露出脾气^2,有时会因为某些事情而生气,气冲冲地离开办公室,甚至几天或几周都不回来。有一次,Mathias 对 Brian Swetland 生气,他把手机摔了出去,愤怒地走出办公室,几分钟后又返回,要求拿回手机,因为他需要手机的内存卡^3。
Mathias 从小就学习如何编程各种计算机,从 Armstrad CPC 到多个 Atari 计算机,再到 BeBox。他为他的 Atari Falcon 写了图形和音频应用(包括一个为 Falcon 编写的音轨应用,他以 Crazy Music Machine^(4) 的名义出售),并且他因撰写关于编程的文章而在法国的计算机杂志中出名。他还将写 Epson 打印机驱动程序作为爱好,开发了 Atari 和 BeBox 的打印机驱动,这些驱动程序被这些公司随系统一起发布。他在 Be 打印机驱动方面的工作为他带来了工作机会;他于 1999 年离开法国,加入了 Be。
Mathias 曾在 Be 工作,直到该公司被 Palm 收购,并继续与 PalmSource 的其余团队一起工作,主要负责图形软件,直到他决定离开,觉得 PalmSource 的方向不适合他。他在 2005 年底与 Joe Onorato 一起离开,加入 Google 开始从事 Android 开发。
基础知识
当 Mathias 加入 Android 时,他从操作系统基础开始。那个时候操作系统基本上还不存在,所以所有加入的成员都参与了构建基本需求的工作。
例如,平台当时还没有 C++ 的核心数据结构(如 Vector 和 HashMap)。在桌面或服务器环境中,这些结构通常不需要,因为它们包含在标准库中,开发者通常会使用这些库。但在 Android 上,尤其是在当时,平台仅包括绝对必要的代码和库。添加标准库会引入太多不必要的部分,占用存储空间,而那时的存储空间有限。因此,Mathias 为 Android 开发编写了这些数据结构的版本,大家都可以使用。
Mathias 还优化了 memcpy^(6) 和 memset,这些是用于处理内存块的低级工具。Memcopy 是系统中至关重要的软件,整个系统都在使用它^(7),它通常在内存密集型的情况下成为性能瓶颈。Bob Lee 评论了这项工作:“他为 memcpy 手写了汇编语言,使其速度非常快,并带来了巨大的性能提升。真是太聪明了。”
PixelFlinger^(8)
Mathias 为图形系统设定的主要目标是实现他所称之为 SurfaceFlinger 的功能,这一功能用于显示由系统中所有应用生成的图形缓冲区(表面)。但是,这个系统依赖于一些尚未存在的低级功能,因此他从这些功能开始开发。
Mathias 的假设之一是,SurfaceFlinger 需要一个 GPU^(9) 来完成工作;它将使用 OpenGL ES 执行从应用程序获取图形数据到缓冲区并将其显示到屏幕上的低级操作。问题是,当时 Android 并没有运行在带有 GPU 的设备上。Android 在那时及整个 SDK 发布之前所面向的设备是 Sooner,它没有 GPU,因此也没有 OpenGL ES。
但 Mathias 看到的未来是,GPU 将成为智能手机的标准。“在加入 Android 之前,我有一点移动平台的经验。我非常明确地意识到,未来我们将使用硬件进行渲染。^(10) 在我看来,软件渲染将会消亡。”
“我的想法是:我要让一切为我们拥有硬件做好准备。问题是,我们没有硬件。我们也不知道何时会发生。所以我想,我负责图形,我就假装自己有 GPU。于是我本质上写了一个 GPU。通过这种方式,我能够使用‘GL’来编写 SurfaceFlinger。它使用的是实际的 OpenGL ES,但默认使用软件。然后,渐渐地,真正的硬件开始出现了。”
当 Mathias 说他写了一个 GPU 时,他的意思是他写了一个 虚拟 GPU;即软件,它执行与 GPU 相同的工作,但由软件代替专用硬件。GPU 不是魔法;GPU 中的专用硬件并没有做任何 CPU 上的软体无法完成的事情。它只是做得更快,因为它有为图形操作优化的硬件。^(11) 在编写这个假 GPU 时,Mathias 提供了一个软件层,来处理通常由 GPU 处理的图形操作,将这些命令转化为现有 Android 显示系统可以理解的低级信息。
他编写的 OpenGL ES 层向一个处理纹理三角形绘制的下层发出了命令,^(12) 该下层叫做 PixelFlinger。将 OpenGL ES 放置在 PixelFlinger 之上这一额外的抽象层增加了工作量和开销,如果 Android 只面向单一设备,这种做法是没有意义的。但在一个 Android 面向未来的世界中,未来几乎肯定包括 GPU 硬件,这意味着 SurfaceFlinger 只需要编写一次,目标是 OpenGL ES。当未来与 Mathias 的愿景匹配且 GPU 可用时,它将继续按原样工作,但速度会更快(使用硬件,而不是基于软件的 PixelFlinger)。
Mathias 编写 PixelFlinger 虚拟 GPU 的方法是 Android 初期采取的产品与平台方法的典型例子。^(13) 产品方法是团队尽可能快速让初始手机工作,这样做不会花费太多时间。但 Mathias 采用的平台方法,通过构建超越初始发布版本的软件层次,最终证明对 Android 长期有利。“必须经历那一步,以便为硬件到位时做好准备。同时,也为了说服人们,这是必须要做的。”
这种长期的图形系统方法以及平台的其他部分,正是团队在早期阶段所采用的一种策略。总体而言,团队非常务实,倾向于组成小型而高效的团队,并在推进 1.0 的过程中做出快速且务实的决策。但团队早期做出的一些决策及其所需的额外工作,正是因为它们是平台未来发展的正确选择,尽管那个未来并不确定。因此,尽管团队的目标是发布 1.0,他们仍然力图构建一个能够超越这个单一发布日期的、面向未来的 Android 平台。
PixelFlinger 在 Android 手机中的生命周期是有限的。它对早期开发中使用的 Sooner 设备至关重要,但搭载 1.0 的 G1 已经具备了 Mathias 所期望并预测的 GPU 能力^(14)。PixelFlinger 的重要性不在于它为特定产品提供的功能,而在于它对平台的意义,构建了能够推动架构和生态系统走向硬件加速未来的前瞻性能力。^(15)
SurfaceFlinger
一旦 PixelFlinger 和 OpenGL ES 正常工作,Mathias 就可以实现 SurfaceFlinger。应用程序将图形对象(按钮、文本、图像——等等)绘制到内存中的缓冲区,然后 SurfaceFlinger 将该缓冲区发布到屏幕上,用户可见。SurfaceFlinger 本质上是应用程序中发生的高级图形操作与他之前编写的 OpenGL ES 层之间的胶合剂,负责复制缓冲区并将其显示给用户。应用程序渲染和屏幕像素显示的分离是有意为之;Mathias 的设计目标之一是通过确保没有应用程序能够导致其他应用程序的渲染性能问题,从而实现平滑的图形渲染(这与 Android 平台的整体安全策略有关,其中始终保持应用程序之间的清晰隔离)。因此,应用程序会将图形绘制到缓冲区中,SurfaceFlinger 会负责后续处理。
硬件合成器
Mathias 编写的图形系统的另一部分是硬件合成器(HWC)。SurfaceFlinger 负责将 UI 图形绘制到屏幕上的窗口中。但有几个窗口需要组合在一起,以生成屏幕上的最终像素。

一个典型的 Android 屏幕示例,显示了状态栏、导航栏和主屏幕
想象一下用户看到的典型 Android 屏幕。上面有一个状态栏(显示当前时间和各种状态及通知图标)、一个导航栏(包含返回和主页按钮),最后是实际的前景应用程序(或主屏幕)。也可能有其他窗口,如在前景应用程序上方的弹出菜单。
所有这些都是独立的窗口,通常运行在不同的进程中。例如,导航栏和状态栏由系统进程管理,而应用程序窗口则由应用程序进程拥有。这些窗口需要以某种合理的方式一起显示,这是硬件合成器的工作。
Mathias 提出的 HWC 方案是使用专用图形硬件,称为硬件覆盖层,^(16) 该硬件为每个应用程序提供专用的显示内存,避免了所有应用程序共享同一视频内存的开销。使用覆盖层硬件还节省了功耗,并为应用程序提供了更高的性能。通过使用专用的覆盖层硬件,系统避免了使用耗电量较大的 GPU 来处理这些简单且频繁的窗口操作。此外,使用覆盖层使得 GPU 可以被应用程序使用,^(17) 以加速游戏或其他图形密集型操作。
他们的解决方案不是手动在屏幕上绘制每一个窗口,或者通过 OpenGL ES 告诉 GPU 来绘制它们,而是 HWC 将每个窗口发送到不同的覆盖层。然后显示硬件将这些覆盖层合成到屏幕上,使其看起来像是一个无缝的信息屏幕,而不是实际上是几个完全不同的进程。
问题在于,覆盖层在实际使用中很难操作,因为每个设备的覆盖层数量和功能都不相同。但是,考虑到 G1 的 GPU 限制,以及该设备上相对较好的覆盖层支持,Mathias 和 Jason Sams 提出了一种创新的解决方案。与其直接在 HWC 中处理覆盖层的无限变化,他们的软件会告诉底层硬件 HWC 需要什么,硬件要么支持他们的要求,要么 HWC 会退回使用 OpenGL ES。随着时间的推移,硬件厂商看到了直接处理这些覆盖层操作的好处,并将其作为在平台这个关键领域为设备提供额外性能的一个方向。
Mike Reed 和 Skia
Mathias 的所有工作都基于需要在屏幕上展示某些内容:应用程序的图形内容。为应用程序绘制图形内容的系统也需要被创建。为此,Android 使用了一个名为 Skia 的渲染系统,这个系统最初是从 Mike Reed 那里收购的。
如果“连续的图形创业者”真的是一个存在的概念,那么 Mike Reed 就是其中之一。
Mike 比许多早期的 Android 工程师晚才开始编程,至少与他们相比是这样。Mike 获得了科学和数学的大学学位。但 1984 年,原版 Macintosh 发布,并出现在他的校园里。“那一切都改变了。我想做图形设计,因为 Mac 正是展示了这一点。所以我拿到了数学学位,但自学了编程。”
Mike 在研究生毕业后成功进入了 Apple 工作(“我差点才拿到那份工作”),在那里他遇到了 Cary Clark,未来的 Skia 联合创始人。^(18) 在 Apple 工作几年后,Mike 离开了并创办了 HeadSpin,开发了一款用于 CD-ROM 游戏的游戏引擎。HeadSpin 被 Cyan 收购,Cyan 是游戏 Myst 的开发商,而 Mike 随后离开去创办了一家新的图形技术公司,名为 AlphaMask。AlphaMask 被提供移动设备浏览器软件的公司 Openwave 收购。
Mike 在 2004 年离开了 Openwave,并与他的前 Apple 同事 Cary 一起创办了 Skia,开发了一款图形渲染引擎。Skia 将其引擎授权给多个客户,其中包括一些位于加利福尼亚的客户。在一次 Mike 去加州的旅行中,Cary 建议他与一个名为 Android 的初创公司见面,Android 由 Cary 的一些前同事在 WebTV 时期共同创办,创始人包括 Andy Rubin 和 Chris White。
2004 年底,Android 仍然很小,只有两位联合创始人以及新员工 Brian Swetland 和 Tracey Cole。Android 正在从构建相机操作系统转向构建手机操作系统。然而,Andy 知道他们需要一个渲染引擎来显示 UI,因此他支付给 Mike 一笔评估许可证费用,并同意之后再联系。但 Mike 没有收到回应:“Andy 就这样消失了,他没有回复我的邮件。”
几个月后,在 2005 年夏天,Andy 最终联系了 Mike。“他说,‘抱歉我消失了,但我现在是通过一个新的邮箱地址联系你。’果然,他发来的邮箱地址是 something@google.com。他说,‘嘿,我被收购了,我们应该完成那个许可证的事情。’”
但 Google 并不是仅仅成为 Skia 渲染引擎的另一个许可证持有者,而是收购了 Mike 的公司。毕竟,Android 正处于招聘阶段,收购可以是一个有效的方式(如果你有足够的资金)来迅速招聘多位员工。
这项收购在 2005 年 11 月 9 日宣布,来自 Skia 的四位工程师(Mike、Cary、Leon Scroggins 和 Patrick Scott)于 12 月开始加入。
谈判的一个重点是地点。Mike 和 Cary 多年前就决定离开加利福尼亚,定居在北卡罗来纳州,他们并不太热衷于回到湾区。谷歌同意将团队留在北卡罗来纳州,在那里他们建立了新的 Chapel Hill 办公室。^(19)
团队开始在谷歌工作后,他们着手将 Skia 打造成 Android 的图形引擎。底层渲染软件本身已经相当完备;他们在 C++ 中完全支持 Android 所需的各种 2D 绘图操作(如线条、形状、文本和图像)。事实上,Skia 在 Android 中的原始图形功能自早期以来几乎没有变化(尽管在这过程中进行了一些重大改进,例如硬件加速)。但是鉴于 Android 选择 Java 作为应用程序的主要编程语言,他们需要让 Skia 能够通过 Java 调用,而不是 C++,因此团队编写了 Java 绑定。^(20)
为 Skia 编写绑定并将引擎集成到 Android 平台的其余部分并不太难,因此 Skia 团队很快就接手了几个其他项目。 其中一个项目——新的 UI 系统——寿命很短。Mike 的团队建议 Android 使用 Skia 现有的 UI 显示系统。他们已经有一个可用的系统,开发人员通过 JavaScript 和 XML 的组合来编程。但由于转向 Java,以及 Joe Onorato 的一些深夜工作,^(21) 团队走上了不同的道路。
第十二章:媒体
当软件工程师谈论媒体时,他们通常指的是多媒体,即音频和视频。这些技术彼此非常不同,并且都需要深入的领域专业知识。因此,工程师通常只专注于其中一种,而不是两者都做。然而,音频和视频工程师通常会被集合到同一个“媒体”团队中。也许是因为它们都需要设备提供强大的性能和内存——并且在软件中进行极端的优化——才能确保为用户可靠地工作。
戴夫·斯帕克斯与铃声
戴夫·斯帕克斯一生只上过一门编程课,那就是他高中二年级时的 Fortran 课程。在那门课上,编写程序的方式是将代码输入穿孔卡片,然后用橡皮筋包裹起来,快递到区办公室,程序在那里执行。几天后,学生们会收到程序的打印输出结果。^(1)
戴夫对教室后面那台老旧的 Monrobot XI 系统更感兴趣,这是一台大约 1960 年左右的机器,使用旋转磁鼓进行存储。他学会了如何在那台老系统上编写机器代码,在这个过程中几乎没通过 Fortran 课程。
他的编程生涯始于高中毕业后,那时他在 RadioShack 工作。有一天,雷·杜尔比^(2)来到商店寻求帮助;他想要一款程序,将自己的股票数据下载到电子表格中。经理指着戴夫说,他可以帮忙。写完一个程序并收取 50 美元后,戴夫成为了一名职业程序员。
在 2000 年代初,运营商要求手机支持各种铃声格式。更复杂的是,不同运营商使用不同的格式,因此手机制造商必须支持多种格式,以便能够将设备销往不同的市场。
雅马哈提供了一款专用的合成器芯片,能够处理这些要求,每部手机的成本为几美元。制造商总是寻找降低成本的方法,于是 Sonivox 公司推出了一种基于软件的解决方案,每部手机只卖一美元。
戴夫·斯帕克斯当时负责 Sonivox 的那个产品,当安迪·鲁宾打来电话时。
随着 Android 计划开源操作系统,安迪的需求与 Sonivox 的典型客户不同;他不仅想要这个产品,还希望发布源代码,从而有效地消除未来的销售机会。戴夫记得这笔交易时说:“这将来会开源。这里有一大笔钱。”
这笔交易发生在 2007 年初。3 月,戴夫来到了 Google,并与 Ficus Kirkpatrick 一起花了几个小时将那款软件集成到系统中。突然,Android 可以播放铃声了。
几个月后,安迪打电话给还在 Sonivox 的戴夫,邀请他加入 Android 团队建立媒体团队。戴夫于 2007 年 8 月加入了 Android。
马尔科·内利森与音频
在 Ficus 使 Sonivox 软件能够支持铃声后,他还成功让一首 MP3 铃声播放起来:“Crazy”——Gnarls Barkley 的歌。Joe Onorato 解释道:“mp3 播放是非常繁琐的工作。等他把那个功能搞定后,我们需要一个铃声。他提交了‘Crazy’的 MP3 文件,那就成了最终的铃声。”
随着所有 Android 手机在每个电话中播放相同的铃声,这首歌让每个人都快受不了了……你明白的。
团队需要帮助将铃声系统普及化,因此他们雇佣了一个已经从事音频软件开发多年的专家:Marco Nelissen。
在荷兰上高中时,Marco 的父母给他买了一台 Commodore 64。最初他只是玩游戏,但很快他就开始在上面编程,学习 BASIC 语言,然后是汇编语言。他写了文本编辑器,接着开始玩多媒体应用程序,包括一个名为 SoundTracker Pro 的音乐序列应用程序。^(3)
大学毕业后,他继续从事多媒体工作,首先在一家为 Philips CD-i 平台编写软件的公司工作,随后加入了 Be 公司。像许多 Be 的同事一样,他在 Be 被 Palm 收购后加入了 Palm。Marco 在 PalmSource 待得比大多数团队成员都长,因为大多数人早在 2006 年初就已经加入了 Google,开始在 Android 项目中工作。Marco 最终于 2007 年 1 月加入了 Android 团队。
Marco 深入研究了 Android 的音频功能。他的第一个项目是增加日益重要的选择不同铃声的功能。“不是我不喜欢那首歌,而是当你听到每隔几分钟别人电话响起时都听到同样的声音,实在是让人烦。”
他继续从事声音和多媒体方面的工作。他为模拟器(团队用于调试软件的工具)增加了音频功能,并最终编写了 Android 的第一个音乐应用程序。他还为 Eclair(Android 2.1)版本编写了几个首批动态壁纸(声音和音乐可视化效果),这些壁纸与 Nexus One 一同发布。
AudioFlinger
另一个需要解决的音频问题是 G1 的音频问题。该设备的原 HTC 音频驱动程序有很多 BUG,甚至像在已经播放的声音上同时播放第二个声音这样简单的操作都会导致设备重启。Android 团队无法访问该驱动程序的源代码,因此他们通过在驱动程序之上增加一个名为 AudioFlinger 的层来规避这个问题。
Mathias 根据自己编写 SurfaceFlinger 的经验想出了这个名字。SurfaceFlinger 解决了图形方面的一个相关问题,许多应用程序生成像素数据缓冲区,SurfaceFlinger 将这些缓冲区显示在屏幕上。类似地,AudioFlinger 将系统中的多个音频流合并成一个流,然后发送到驱动程序,而不会(这是关键部分)导致设备重启。Mathias 与 Marco、Arve 和 Ficus 合作,成功地为 G1 实现了它。它本应只是该平台针对特定设备的临时解决方案,但正如软件中常见的情况一样,它在超出其有效性之后仍然存在,直到最终被重写,以便系统能够更直接地与没有这些历史问题的驱动程序进行通信。
没人喜欢的视频代码
处理视频很复杂。首先,视频需要编解码器^(4)来加载和保存视频文件。视频软件还需要能够播放由编解码器加载的内容。一旦这些工作都完成,你还需要对其进行优化,以便快速完成,因为无法流畅播放的视频就不再是“视频”,而更像是“让人沮丧”。
与此同时,软件需要能够与硬件进行通信,这很棘手,因为专用视频硬件在不同设备之间可能差异很大。
由于团队规模如此之小,实施视频所需的一切会非常困难。所以 Andy 决定购买必要的技术,而不是自己编写。他让 Ficus Kirkpatrick 查看一些选项,但让他专注于一家名为 PacketVideo 的公司。当时,PacketVideo 许可了一个完整的软件套件,可以实现 Android 所需要的所有功能。
交易即将达成;Ficus 的调查更像是一次理智检查,而非深入分析。Ficus 记得,“Andy 告诉我,无论如何他都会做这笔交易。”像团队其他成员一样,他当时忙于其他事情,看起来这笔交易是板上钉钉的结论,所以他没有花太多时间去评估情况:“我当时觉得这无关紧要。我认为代码不好,但没有提出异议。”
他简要调查了其他选项。他否决了一个替代方案,因为他们的代码状态。那家公司过于专注于让他们的产品在 Windows 上运行,以至于在软件中埋入了假设,使其无法在任何其他操作系统上使用(比如 Linux,这是 Android 所需要的)。相比之下,PacketVideo 是一个更好的选择。“它可能是我看过的所有媒体框架中最不糟糕的。”
Andy 提出的交易对 PacketVideo 来说很尴尬;他提出的方案是将他们业务的核心部分交出去。这家公司通过许可他们的视频软件赚钱。Android 不仅需要他们代码的功能,还需要代码本身。Android 计划将平台的所有代码开源,包括 PacketVideo 的代码。所以 Andy 提出的交易是,Android 将拿走他们的软件并公开发布,实质上摧毁了他们未来的任何许可可能性,因为任何潜在客户都可以直接复制 Android 代码。Ficus 说:“Andy 向他们推销的说法是,‘你们的业务将从许可转向专业服务。我们会给你们一些钱,以帮助你们过渡。’”
交易达成了(在 Tom Moss^(5))的帮助下),代码已经集成,而 Android 团队却……不高兴。^(6) Ficus 记得说:“代码不是很好,优化起来真的很困难。”
Mathias Agopian 同意了。“从技术角度来看,这是个灾难。PacketVideo 在纸面上看起来真的很不错:大量的编解码器、播放、录制、视频、音频。从纸面上看,问题解决了。但我们花了许多许多年修复,最终重写了一切。”
Ficus 继续说道:“可能我唯一的好贡献就是拒绝发布他们的 API,只发布了极其简单的 MediaPlayer/MediaRecorder [API]。这是一个低复杂度、低能力的 API,它使得很多内部工作得以重构。”也就是说,通过只向应用开发者提供简单且通用的视频功能,而不是直接暴露更先进的 PacketVideo 功能,Ficus 确保了视频实现的细节可以在之后发生变化,当团队有更多时间处理这个问题时。
事实上,最终确实发生了这种情况。几年后,这一层系统被完全重写,成为了一个名为stagefright的组件。Andreas Huber,当时媒体团队的一名工程师,一直在稳步重写 PacketVideo 代码的部分内容。最终他意识到旧代码再也没有被调用,于是他删除了它,PacketVideo 的代码也就此消失了。
第十三章:框架

每当 Dan Sandler 访问 Mountain View 办公室时,他通常会在白板上留下些艺术作品。这次,他在其中一次出访时留下了这幅画,出现在框架区。
Framework^(1)是 Android 团队用来描述核心平台中大部分内容的术语,涵盖了内部操作系统级别的内容(几乎支撑整个系统的除内核外的所有软件部分),以及应用程序用来访问这些功能的 API。框架功能的示例包括:
-
包管理器,负责在设备上安装和管理应用程序。
-
电源管理,例如控制屏幕的亮度设置(屏幕是任何设备上最耗电的部分)。
-
窗口管理,在屏幕上显示应用程序,并在打开和关闭时进行动画效果。
-
输入,接收来自触摸屏硬件的信息,并将其转化为输入事件,路由到应用程序中。
-
Activity 管理器,处理 Android 的多任务系统,决定在设备内存不足时应该关闭哪些应用。
当框架工程师在 2005 年底开始加入 Android 时,框架的所有内容都不存在,因此当时加入 Android 团队的人们必须一点一点地构建框架。
Dianne Hackborn 与 Android 框架
那位最能定义[Android 平台]形态的人显然是 Dianne。我敢肯定她可能会低调自己在这里的影响力,但她错了。
—Ficus Kirkpatrick
到 2005 年底,部分将成为框架的组件已开始构建,但仍有很长的路要走,包括供应用程序使用的 API 和系统所需的所有其他功能。然后,Dianne Hackborn 加入了团队。
Dianne(团队中也称她为“hackbod”^(2))是大多数团队成员公认的,最了解整个 Android 框架和整体平台的人。首先,她对平台中所有部分如何协同工作有全面的了解,同时也对操作系统和 API 有着广泛的知识。
另外,她写了大部分的框架代码。
Dianne 来自计算机界的名门望族。她的父亲曾在惠普创立了打印机部门,并曾一度被考虑担任 CEO。在其他孩子通过玩电子游戏接触电脑的年龄段,她却已经涉足系统设计。“我会研究系统是如何工作的,以及它与应用程序和线程的协同方式。”
大学毕业后,她在 Lucent Technologies 工作,并在闲暇时间玩 BeOS(“编写框架,一些应用程序,UI 布局框架……类似的东西”)。最终,她希望这项工作能成为她的主业,因此她搬到了湾区,开始在 Be 公司工作。
“那时正值互联网泡沫时期。你在一家没有盈利、也不知道如何赚钱的公司工作,但每个人都希望能参与操作系统的开发。那就是他们来这里的原因。这里不是为了赚钱。”^(3)
Dianne 在 1999 年底加入 Be,成为那里一群人中的一员,她之后又在 PalmSource 与这些人合作,随后在加入 Android 时再次与他们共事。她在 Be 负责框架工作,之后又在 PalmSource 继续从事相同的工作。
在 Be 公司,Dianne 参与了 BeOS 下一个版本的开发,但这也标志着该操作系统的终结。“他们试图与微软竞争。你无法与一个根深蒂固的平台竞争。除非他们自作自受,否则这是不可能的,因为他们的生态系统已经有了如此强大的势头,你做得比他们更好,他们有几年时间来对你做出反应,直到这变得有意义。”
“这就像是一个‘鸡与蛋’的难题。你需要吸引用户来让应用开发者对你感兴趣,而你也需要吸引开发者,才能让用户对你感兴趣。你可以吸引一些用户,但每当你尝试积累势头时,主导平台总能找到方法去解决特定市场的问题并击败你。这个过程几乎是不可能的。”
最终,Palm 收购了 Be,因为 Palm 计划为其设备打造一个更强大的操作系统,并需要具备相关专业知识的工程师来实现这一目标。这也是 Dianne 第一次接触到移动计算。“当时我从未考虑过移动领域。但一旦我开始了解 Palm,我就变得非常感兴趣。这似乎是与微软竞争的方式。它是一种新型的设备,如果你能成为该设备上的平台,那么你将拥有比 Windows 更大的生态系统,你就有机会。你能看到未来的趋势。硬件正在变得越来越强大,而市场已经比 PC 更大。”
然而,PalmSource 却陷入了困境。Palm 与 PalmSource 分开时,最初的构想是,PalmSource 会提供 Palm(以及其他公司)所使用的操作系统。但到了 PalmSource 发布 Palm OS 6 的时候,Palm 决定继续使用他们在 Palm 和 PalmSource 分裂时开始使用的操作系统。接着,当团队几乎完成为三星设备打造的高质量操作系统时,协议破裂。之后,再也没有其他买家对该操作系统产生兴趣,因此公司开始寻求被收购的机会。
当时,Dianne 和她的团队不得不应对一个有趣的移动操作系统动态,这个问题后来在 Android 上以更成功的方式浮现。“要让手机制造商对其他人的平台感兴趣真的很难。他们做自己的软件,而且他们害怕手机变得和 PC 一样,成了由一个软件供应商控制的平台,最终让硬件商品化。”
当硬件公司自行开发操作系统的模式在软件较为简单时是行得通的。对于一部翻盖手机来说,处理电话和联系人信息完全在这些公司能力范围之内。但随着所需功能和特性的不断增加,尤其是在 iPhone 推出之后,这些公司很难跟上。iPhone 发布后,急需操作系统的公司寻找的东西远比他们自己能做的要复杂,因此他们更愿意与 Android 合作。
“软件变得比硬件更有价值。你大部分的投资现在都在软件上。如果是这样的话,那么谁能在软件上投入最多,谁就会最具吸引力,而这可能是一个致力于跨不同硬件平台的软件的人。”
Palm OS 6 的一部分是一个强大的 UI 框架。摩托罗拉,一家有意收购 PalmSource 的潜在公司,对这个框架以及 Palm OS 6 本身都非常感兴趣,想将其用于自己的设备。但摩托罗拉的收购尝试失败了,而 PalmSource 则被 ACCESS 公司收购了。“被摩托罗拉收购本来会很有趣。我们都在希望那样。他们想拿我们做的事情并利用它。”然而,ACCESS 对于当前的方向并不认同。
收购后,ACCESS 改变了团队的操作系统战略。Dianne 和她的团队结束了他们的工作。“PalmSource 完了。手机制造商不想接触别人的平台,因为他们不想成为一个推动者。我看到我的团队一个个离开(我当时负责框架团队)。Mathias 和 Joe 要离开了,他们来找我说‘你应该来 Google—这里有很多酷的事情。’他们给了我一些暗示:‘这是一个平台…它是开源的…’在 Google 做开源的移动平台工作,你不必担心钱?怎么能拒绝呢?简直太完美了。”
Dianne 于 2006 年 1 月加入 Google,并开始加入 Android 团队。
她早早就接触到了 Google 关于 Android 战略的看法。“当我加入时,Larry 和 Sergey 的谈话方式,以及 Andy 的展示方式,他们不仅仅想要一款产品。那比那更宏大:是 Google 未来生存的问题。他们不希望有一个拥有封闭专有平台的公司主导这个领域,就像微软拥有 PC 平台一样。这并不是为了赚钱。”^(5)
活动
当 Dianne 狂热工作时,很难超越她的编程能力。她有一个明确的愿景,便直接坐下来敲代码实现它。
— Jeff Hamilton
在她加入 Android 后,Dianne 开始参与许多现在被称为框架的基础模块工作。其中一个模块是 Activities,它是从 Joe Onorato 的一些初步工作中接手过来的。
Activities,起源于团队在 PalmSource 时更长远的构想,是一种独特的 Android 应用管理方式。在传统操作系统中,应用程序启动时会调用 main() 方法,然后进入一个循环(绘制、轮询输入、执行必要的计算等)。而在 Android 中,应用程序被拆解成一个或多个“活动”模块,每个模块都有自己的窗口。Activities(和应用程序)没有 main() 方法,而是由操作系统响应事件(如活动的创建/销毁、用户输入等)进行调用。
Activities 的另一个重要特点是它们定义了可以从其他应用程序调用的特定入口点,比如系统 UI 中的通知或快捷方式,可以将用户带到应用程序内部的某个位置。
Dianne 说:“Palm 对移动设备有很深的理解。在那里我们学到的一件事是,移动应用与桌面应用有根本的不同:用户一次只能使用一个应用,并且这些应用通常较小,专注于某个特定任务。从这一点出发,我们需要让应用能够轻松协同工作。Palm OS 有一个叫做‘子启动’的技巧,允许一个应用有效地调用另一个应用,做一些诸如显示 UI 以便用户添加联系人之类的操作。我们认为这是移动应用中一个重要的特性,但我们需要将其规范化,形成一个定义明确的概念,以便它在复杂的多进程保护内存(和应用沙箱)环境中更为健壮并且有效。因此就有了 Activities,定义了应用可以如何暴露部分功能,供其他应用(和系统)按需启动。”
Activities 对于 Android 来说是一个强大的概念。它们也是工程团队第一次大规模意见分歧的核心问题之一。与一些人偏好的传统方法相比,Activities 确实更为复杂。特别是,Android 的应用生命周期(处理活动创建/销毁等)仍然是难以理解的,而处理其复杂性往往是许多 Android 开发者的一项艰难且容易出错的任务。
正如 Jeff Hamilton(我们很快就会了解的框架工程师)所说的,“在 Android 的早期,有两个关于操作系统应该是什么样子的竞争性愿景。一个是围绕 Activities 的模糊特性,另一个是有一个被调用的 main() 方法。Dianne 和 Joe 推动的是更加模块化的应用程序设置方式,其中包含 Activities。”
“还有一些其他人,比如 Mike Fleming^(6),他们倾向于推动更简单的模型。那里曾经有一段时间的激烈冲突。”
Mike Fleming 说:“我曾对应用生命周期持怀疑态度。我担心它太复杂了。” Wei Huang^(7) 同意:“在某些方面,我认为活动生命周期过于复杂了,它变得有些失控。”
但团队决定采用活动方式。Jeff 解释了事情是如何发生的:“Dianne 对她想要的有一个清晰的愿景,她只是坐下来把它打出来。这就是方法,因为她很有生产力,事情也都完成了。”
这种决策模式在其他地方也有体现,比如 Joe 实现的初始视图系统。团队没有太多时间开会、组成委员会或辩论事情该如何进行,所以最终总是有人直接敲定一个解决方案,然后事情就从那里继续发展。正如 Dianne 所说:“当时人很少,如果你做了,就直接做了。人们之间有很多讨论,但都是由正在做事情的人发起的。” Romain Guy(后来加入工作在 UI 工具包的开发)补充道:“在 Android 上,最受尊敬的是有人能够真正把事情做成。” 而且,通常这个人就是 Dianne。
资源
Dianne 还参与了资源系统的开发^(8),这是另一个非常 Android 特有的概念。在 Android 上,应用程序开发者可以在所谓的 资源文件 中定义文本、图像、尺寸及其他元素的不同版本。
比如,你的应用程序中可能有一个按钮,上面应该写 Click,这样用户就知道点击这个按钮。但是,单词 Click 只有在用户讲英语时才有意义。如果他们讲俄语呢?或者法语?或者……任何其他非英语语言呢?开发者使用资源文件来存储不同语言版本的字符串。当按钮填充字符串时,资源系统会根据用户在手机上选择的语言,选择合适的版本。
同样,开发者可以定义屏幕配置的 UI 样式,并根据不同的屏幕密度使用不同的图像尺寸。资源系统会根据用户设备在应用启动时加载适当的变体。
资源,以及它们如何解决特别是变量密度问题的方式,是 Android 作为一个软件平台(而不仅仅是作为一款手机产品)发展的一个很好的例子,即使在 1.0 之前的那些早期阶段。如果团队当时只是针对某个特定设备,并有一个预定义的屏幕尺寸(正如当时大多数厂商所做的那样),那么这些问题就不需要解决。但这样一来,应用就会在最初的假设基础上编写。当不同尺寸的屏幕出现时,应用就会显示不正确。
Dianne:“这些设备与桌面不同,因为设备对应用的影响比桌面更大。在桌面上,你可以有更大的屏幕,但这对应用并没有太大影响,你可能只是能调整窗口的大小。但在这些设备上,如果屏幕变大,应用需要能够在更大的屏幕上正确绘制。”
另一个因素是屏幕密度。^(9)“在桌面上,屏幕密度永远不会变化。但我们知道,移动设备的密度会发生变化。我们在 Palm 公司看到过这种情况。我们需要设计一些东西,让平台能够在长期内不断发展,因为我们看到了 Palm OS 及其更简化方法的问题。让它支持不同的屏幕密度时,完全是一场灾难。我们一直都[对于 Android 平台]抱着这样的想法:‘我们在为移动设备构建这个,但我们希望它能够扩展,长期应对其他使用场景。’”
相比之下,iOS 和 iPhone 最初并没有考虑屏幕密度。“苹果没有考虑这些问题。苹果是为数不多的既能做高质量软件开发,又专注硬件的公司之一。大多数硬件公司只关注硬件产品,软件只是硬件所需的一部分。而苹果能够将软件作为一个长期投资的方向,独立于某个特定硬件产品。不过你仍然会看到他们在硬件方面的思维,比如‘我们想改变屏幕尺寸……我们没有考虑到这一点。’”
WindowManager
Dianne 说:“我要做一个窗口管理器,”然后嘀嘀嘀嘀,窗口管理器就出来了。
—Mike Cleron
Dianne 早在 1.0 发布之前,就编写了 WindowManager,它处理窗口的打开、关闭、动画进场和动画出场。这个工作很有意义,因为它不仅解决了复杂的问题,还因为 Dianne 在做这件事时,只是她众多工作中的一项。^(10)
软键盘
在 1.0 发布后,仍然有很多工作要做。Dianne 当时与框架团队的 Amith Yamasani 一起工作的一项任务就是支持软键盘,即触摸设备所需的屏幕键盘。
原版 G1 配备了硬件键盘。进入应用程序时需要将键盘滑出。这个机制工作得很好(事实上,很多智能手机用户在几年后仍然偏爱硬件键盘,特别是黑莓的粉丝)。但对更大屏幕和更小设备的需求意味着支持全触摸设备和屏幕上的虚拟键盘变得至关重要。事实上,随着即将发布的 Cupcake 版本,设备将不再配备硬件键盘。
按照典型的 Android 开发方式,软键盘并不是直接硬加到框架中的。Android 因为要在性能和发布时间之间做取舍而闻名,但团队始终优先考虑创建通用平台能力,而不是针对特定产品特性的黑客解决方案,这也是他们键盘解决方案的做法。团队创建了一个系统,提供可扩展且灵活的通用输入支持。例如,键盘支持不仅仅被称为键盘,而是输入法编辑器(IME)。仅仅提供常规键盘的支持是不够的,系统需要能够接受来自任何输入机制的输入,包括语音输入。
与此同时,输入支持不仅仅是作为框架内部的机制,而是作为一个可扩展的特性,开发者可以利用这一点。Android 提供了输入法框架(IMF),它接受任何用户提供的 IME 输入,而不仅仅是随 Android 系统一起发布的键盘。也就是说,Android 不仅仅为用户提供了软键盘;他们还为开发者提供了 API,让他们创建自己的键盘应用,供用户选择使用。短期需求是提供一个足够好的输入系统,满足大多数使用场景。但团队意识到,可能还会有其他用户想要的体验,或是其他开发者可以提供的功能,因此他们构建了一个允许实现这些功能的系统。即便市场上只有少数几款 Android 设备,团队仍在进行长期布局,预见到可能会有一个庞大且多样化的设备和用户生态系统。
戴安娜说:“我不记得曾经考虑过将其硬编码到平台中的路径。从能够满足不同语言需求的实际考虑出发,我们认为这应该是一个用户可选择的组件。”
IME 支持是吸引许多开发者(和用户)早期加入 Android 的一个重要例子。早期的设备,如 G1,可能并不是最美观的智能手机,但开放生态系统的力量和灵活性吸引了许多用户和开发者。尽管 iPhone 最终提供了除了 iOS 自带的键盘外,还可以安装其他键盘应用的功能,但这发生在很晚之后,远远晚于 Android 开发者提供这些应用的时间。
2009 年,Shumin Zhai 在 IBM 从事研究工作。他在研究替代输入机制,使用他自己开发的一款应用 ShapeWriter^(11)。这款应用不需要逐个输入字母,而是允许用户在键盘上滑动手指,在字母之间画出形状,从而输入单词。这个键盘通过使用概率和启发式算法,解读这些形状为单词,来确定用户正在输入的词。
Shumin 在 2004 年与 Per Ola Kristensson 一起开发了 ShapeWriter,并最初在 Windows Tablet PC 上发布。2008 年,他们将 ShapeWriter 发布到 iPhone,但它只能与他们提供的记事本应用一起使用,因为当时 iPhone 没有类似 Android IMF 的功能,所以无法替代系统键盘。当 Android 在 2009 年中期的 Cupcake 版本中发布了对 IMF 的支持后,Shumin 将 ShapeWriter 的重点转向了 Android,并于当年晚些时候在 Android Market 发布了这款应用。^(12)
他特别喜欢为 Android 开发^(13),因为这让他能够进行实验,能够将系统键盘换成自己的键盘,从而提供这种新功能。Shumin 是一位研究员,虽然这看起来似乎不是一个庞大的目标市场,但就在同一时期,一家公司在 Android 平台上发布了一款名为 Swype 的流行应用,拥有类似的手势输入功能。
Shumin 最终加入了 Android 团队,并领导了实现 Android 标准 IME 手势输入的团队。如今,Android 的键盘默认内置了这种绘制单词的功能。但 Android 仍然允许开发者提供自己的键盘应用,以进行自定义和开发者希望创建的功能。
Jeff Hamilton 逐步在技术栈中晋升
尽管 Dianne 的生产力令人传奇,但要让整个框架真正成型,还有很多工作超出了她一个人能够完成的范围。还有一些其他人也在编写大量的框架代码,其中之一就是 Jeff Hamilton(团队内称他为“jham”)。
Jeff 和 Dianne 在同一天加入了 Google。他们曾在 Be 和 PalmSource 一起合作过框架代码,现如今准备在 Android 上再次合作。
Jeff 的工作生涯始于大学时期,在 Be 公司实习时开始了他的平台开发工作。他在面试时实际上失败了,因为他关于 BeOS 中中断处理程序的工作原理的回答有误,BeOS 与 Linux 的处理方式不同。他回家后研究了这个差异,重新提交了解释,并给出了正确答案,团队改变了主意,决定聘用他在夏天实习,并在他大学期间继续工作...最终在他大学毕业后,聘用了他成为全职员工。
在 Be,Jeff 在内核团队工作,负责硬件驱动开发,如触摸屏显示器和 USB。他还很好地了解了如何在一个充满活力的硅谷公司开始工作:“第一天,他们把我带到我的工作区,那里有一个机箱和键盘。他们说,‘那边有主板,去找 George 要个 CPU。’他们没有内存条,我得去 Fry's 买。”^(15)
大学毕业后,Jeff 全职加入了 Be,后来在 2001 年 Be 被收购后加入了 PalmSource。但和团队里的其他成员一样,包括 Joe、Dianne 和 Mathias,Jeff 最终也厌倦了 PalmSource。“到 2005 年 8 月,情况已经很明显,他们没有客户了。”他搬到了德克萨斯州奥斯汀,因此开始在那个地区找工作,发现摩托罗拉有一个非常合适的机会。“那是一个本地的工作。他们想要建立一个新的现代智能手机操作系统,能够在所有手机上发布,而不是只做一个一次性的产品。我加入的团队已经签署了一项收购 PalmSource 的协议^(16),他们说我非常合适。听起来一切都很不错,所以我在 2005 年 8 月辞去了 PalmSource 的工作,加入了摩托罗拉。”
但在 PalmSource 交易关闭之前,ACCESS 突然出价更高,PalmSource 选择了更高的报价。由于摩托罗拉的智能手机操作系统计划被叫停,Jeff 没有太大的动力留下来。幸运的是,他在 Be/PalmSource 的同事们正在面试并加入谷歌的 Android 团队。Jeff 从他的朋友 Joe 那里听说了这个机会。“我说我对搜索和网络一无所知,我不想远程开始新工作,而且我不认识团队里的任何人。Joe 说,‘别担心第一个问题,你已经认识团队的一半人了。来面试吧。’”Joe 通过把 Jeff 引进 Be 的机会,回报了他多年前的帮助:“他说服 Andy 在我还在奥斯汀、在家工作的情况下雇佣我。”
当 Jeff 加入团队时,Android 还不是一个平台,而只是一些随机的代码片段、原型和技术演示。“Joe 有一个窗口管理器的演示,画了一个正方形——屏幕上的基本形状。还有一个人^(17)在做电话功能。Mathias 在做图形工作。但当时没有任何功能。根本没有真正的操作系统。”
Jeff 的第一个任务之一来自 Brian Swetland,任务是为在设备上运行的 Android 应用程序构建一个调试协议^(18)。Jeff 没有从头开始实现自己的系统,而是让 gdb(一个标准的调试工具)运行起来。这意味着要在操作系统上让其他 gdb 需要的东西运行起来,比如线程和调试符号的支持^(19)。
一旦调试工作完成,Jeff 开始了 Binder 的开发。
Binder
Binder 是 PalmSource 工程师在之前的公司和操作系统中熟悉的概念^(20)。Binder 是一个进程间通信(IPC)^(21) 机制。每当操作系统中发生需要多个进程参与的事件时,IPC 是用于在这些不同进程之间发送消息的系统。例如,当用户在 PC 上输入时,系统进程会将包含该信息的消息发送给前台应用程序进程,以处理该按键事件。IPC 系统(在 Android 中是 Binder)定义了这种通信机制。
在 Android 设备上,许多进程始终在运行,处理系统的不同部分。系统进程处理进程管理、应用程序启动、窗口管理以及其他底层操作系统功能。电话进程保持电话连接活跃。前台应用程序是用户实际交互的应用。系统 UI 负责导航按钮、状态栏和通知等等——有很多进程,它们都需要在某个时刻与其他进程进行通信。
IPC 机制通常简单且底层,这正是前 Danger 工程师所希望的。正如 Wei Huang 所说:“Danger 喜欢做事快速。简单且快速。但主要是简单。”然而,包括 Jeff、Joe 和 Dianne 在内的 Be 团队更倾向于采用 Binder 方法,这种方法在 PalmSource 中已经实现,功能更全(且更复杂)。而且,由于 Binder 是开源的,因此可以用于这个新平台。
这种分歧导致了团队之间的问题。Mike Fleming 站在 Danger 一方:“我是一个 Binder 怀疑者。我认为它并没有经过充分的考虑。确实,他们在 Palm 做过,但同样也没有在产品中推出过。”
“我特别生气的是,你必须进行一个阻塞调用^(22),这个调用会在另一方进行一个阻塞调用。我觉得这会导致不必要的线程操作,而且对我的使用案例没有任何价值。而且,原始的 Binder Linux 内核驱动并不完全健壮。要让它真正可靠,需要做大量的工作。”^(23)
Binder 怀疑者没有赢得那场战斗:Jeff 和团队继续推进并实现了 Binder,Binder 成为 Android 框架架构的基础部分。与此同时,Mike 在他的电话工作中忽略了 Binder:“我在 Java 进程和本地接口层进程之间打开了一个 Unix 域套接字^(24)。”
数据库
在 Jeff 让初始 Binder 模块工作后,他转向了数据库。应用通常需要存储信息。如果数据较为复杂,他们需要一个强大且功能齐全的解决方案;他们需要一个数据库。在 PalmSource,Jeff 曾与数据库打交道,但那家公司希望创造一些新的东西。Android 并没有试图发明任何新东西;他们只需要一个解决方案。“我看过 SQLite^(25),我想,如果我们想要建立我们自己的手机并尽快推出,可能不应该从零开始构建自己的数据库系统。SQLite 已经存在——它能用。”于是,Jeff 将 SQLite 库移植到 Android 上,创建了供应用开发者访问的 API,之后他继续转向下一个项目。
联系人和其他应用
因为他已经在处理应用数据,Jeff 被拉入了一个项目,定义应用如何共享数据。某人的联系人数据需要对设备上的其他应用可用(例如,可以拨打电话或发信息给朋友)。这促成了 ContentProvider APIs 的出现,Jeff 随后在开始开发 Contacts 应用时使用了这些 API。“显然,我们应该有一个通讯录和通话记录,于是我开始构建 Contacts ContentProvider,拥有一个通讯录,这样你就可以拨打电话了。”一旦这一功能实现,他继续往上移动软件栈,开始着手开发 Contacts 应用的 UI。
在 Contacts 之后,Jeff 继续参与了平台的其他部分和核心应用。他曾在某个阶段帮助开发短信应用,那个应用主要由 Wei Huang 开发。他还帮助编写了 Mike Fleming 负责的电话软件,之后又协助了电话拨号应用的开发。
当时,Dialer 和 Contacts 是同一个应用的一部分。Jeff 想要在 Dialer 中简化一些操作,于是他创建了一个有争议的 UI 功能,叫做“Strequent”。“在拨号器中,有一个标签是拨号器,一个标签是通话记录,还有一个标签是联系人。我创建了另一个标签叫 Strequent。它是你的星标联系人,接着是你常拨打的联系人。大家觉得这真的很奇怪。我记得 Steve Horowitz^(26)一点也不喜欢它,但 Rich Miner 却喜欢。”Rich 说服 Steve 接受了这个功能。
Jeff 最终参与了大多数核心应用的开发,并最终负责管理应用团队。他记得有一个特别的日历用户问题:“Sergey[Google 的联合创始人]来了。Calendar 应用崩溃了。他的妻子从 Outlook 向他共享了日历。结果发现 Outlook 中有一些带有例外的重复事件,这是我们之前从未见过的。我们的事件解析器崩溃了。”
Jeff 去找 Sergey 解释问题。“‘我们找出了问题:你的日历里有一些我们以前从未见过的数据,我们没有预料到这些数据,导致我们的应用崩溃了。’他说,‘我的数据不会导致你们的应用崩溃!是你们的应用在我的数据上崩溃!’”Jeff 记得多年后这个情况依然清晰。这种与谷歌创始人和高管争论的经历很难忘记。
Jeff 所经历的过程,从系统的最低层开始让本地调试器工作,然后处理核心框架内部和 API,再到数据功能和 API,最后编写使用他构建的某些底层功能的应用程序,^(27) 是团队成员所做工作的一个很好的例子。基本上,在 Jeff 到来之前什么都不存在,所以他帮助逐步创建这些模块,将每个新模块建立在前一个模块的基础上,随着更多功能的上线。以类似的方式,团队中的每个人都从最基础的部分开始构建,并随着能力的提升逐步实现更高层次的功能,最终编写出定义 Android 用户体验的应用程序。
Jason Parks 搞砸了
另一个来帮助 Dianne 框架团队的 Be/PalmSource 校友是 Jason Parks,他于 2006 年春季加入了 Google 的 Android 团队。
Jason Parks(团队称他为“jparks”)在成长过程中有一个口号:“我没有搞砸,但我知道如何修复!”这个口号和概念一直陪伴着他,最终他在自己工作的操作系统中使用了 JPARKS_BROKE_IT 作为错误代码标签。
Jason 很早就开始编程,从六年级时就学习 BASIC。儿童时期和大学期间他一直在编程,但并没有毕业。“我不是很擅长语言类课程,我从来没完成过英语课。我还差二十二个学分才能毕业,但我却意外地申请了一份工作。”Jason 一直在自学 BeOS,因此当他看到 Be 的招聘广告时,他就申请了。
“但我申请了错误的职位;我申请的是一个经理/架构师职位。在他们的系统中,你一次只能申请一个职位。我当时想,‘那就算了,得等他们重置了才能再申请。’结果我收到了一个电话面试的邮件,面试的是我显然不符合资格的职位。”最后他确实获得了面试机会和工作邀请,但职位不同。他问为什么他们会回邀他,明明他申请的是错误的职位,得到的回答是,他们之所以注意到他的申请,是因为他显然不符合该职位的要求。^(28)
Jason 曾与其他未来的 Android 人员一起在 Be 工作,比如 Dianne、Jeff 和 Joe,之后跟随他们转到 Palm,最终离开 PalmSource 加入 Android 团队。
和 Jeff、Joe 一样,Jason 也参与了平台的多个不同领域。他的第一周,他在做处理时区的软件。然后在第二周,他让电话数据正常工作。接着随着时间的推移,他转向了框架和应用的其他部分。
Jason 在整个组织中也扮演了重要角色——让人们去做事。这样的一种方式是作为不同小组之间的调解人。当人们有分歧时(比如各种 Danger 与 PalmSource 派系之间的冲突),Jason 会尽力化解这些问题。“当通讯团队的成员对 API 感到不满时,他会来找我,让我去和他们[框架团队]沟通。Swetland 也是如此。Horowitz 会派我去找 Swetland 跟他谈一谈,平息他的情绪。我和 Mike [Cleron] 以及 Dianne 之间有很好的合作关系。我会向其他人解释事情应该怎么做。”
“这里有很多急性子的人,很多冲突。不仅有 PalmSource/Danger 的问题,还有一些 Google 员工进来说‘你们必须这样做’。但我认为这些冲突对我们有帮助。”
Jason 还会被 Steve Horowitz 指派确保某些事情的发生。“团队中的一些人称我为斗牛犬,因为我是 Steve 的攻击犬。当他需要完成某件事时,他会派我去做。”
框架开发
框架团队上进行的项目清单长得让人难以置信,因为它真的就是 Android 平台的核心。系统的许多其他部分都依赖于 Dianne、Jeff、Jason 和其他人在这个团队中创建的基础工作。而这一切都是从零开始构建的,始于这些人于 2005 年底加入团队时。与此同时,平台的其他部分和应用也在框架之上构建,就像是在飞机飞行中还要建造飞机,而机舱里挤满了乘客,大家都希望飞机在坠落之前能够抵达目的地。
第十四章:UI 工具包

UI 工具包提供屏幕上的大多数视觉元素。按钮、文本、动画,以及绘制这些元素的图形,都是 Android 上 UI 工具包的一部分。
2005 年底,UI 工具包尚不存在(当时几乎没有其他任何东西)。有一种低级图形功能,允许使用 Skia 库在屏幕上绘制一些东西。并且有两个关于如何在该图形引擎上构建 UI 工具包的相互冲突的想法。
在一边,Mike Reed 的 Skia 团队有一个工作的系统,使用 XML 来描述 UI,并用 JavaScript 代码来提供编程逻辑。
另一方面,框架团队更倾向于一种以代码为中心的方法。
这个决定,像 Android 中的许多决策一样,是通过纯粹的努力达成的。Andy Rubin 最近决定 Android 将使用 Java 作为主要编程语言。Joe Onorato 决定是时候深入并用 Java 实现 UI 层了。“基本上是一个愤怒的‘让我们做点什么’时刻。花了一天时间,24 小时的马拉松。^(1) 我把 Views [UI 元素] 展示到屏幕上。”
Mathias Agopian 评价 Joe 说:“他没有告诉任何人。一天早上,他出现并说,‘问题解决了,它现在是用 Java 做的了。现在我们不用再讨论这个问题,因为它已经在那里了。’”
Mike Reed 回忆起决定采纳 Joe 的实现方案:“Joe 来时带来了非常明确的想法。尤其是因为我们是远程的 [Skia 团队在北卡罗来纳州],我们只是退后一步,让它自行解决。”
Joe 向 Andy 演示了他的工作,但效果不如他预期。“第一次我向 Rubin 演示时,他并不怎么印象深刻。我做的第一件事是在 UI 上画了一个红色的 X。显然,那是 Danger 内核崩溃时会绘制的东西。^(2) 我向他展示了我认为是重大成就的东西:‘看,我完成了 View 层次结构!’。但在他看来,这就像是手机崩溃了。他说,‘哇,你让内核崩溃了。’”
但 Joe 的工作是重要的。它使得团队中的开发者能够开始编写其他需要 UI 功能的系统部分。
当然,系统的许多部分在早期开发过程中都在变化,UI 工具包就是其中之一。Joe 构建的系统是多线程的。^(3) 这种方法在 UI 工具包中不常见,因为它需要非常小心的编码,以正确处理那些随意而来的请求,而不考虑线程问题。
2006 年 3 月,在 Joe 编写了初始的 View 系统三个月后,Mike Cleron 加入了 Android。他看到了随着代码库的不断增长,依赖 Joe 的多线程 UI 工具包的复杂性越来越高。
Mike Cleron 和 UI 工具包重写
Mike Cleron 从未想过自己会进入计算机科学领域,直到大学时才改变主意。“我本以为自己会成为经济学专业的学生,直到我上了经济学 1 课。”他的计算机科学课程反而更为顺利:“我非常喜欢大一时的课程,我们学的不是编程,而是数据结构和算法。我觉得二叉树遍历是最酷的事情。真的是个大书呆子。”
“这是我唯一能获得学位的专业,因为这是唯一一个当我大脑因疲劳而几乎停止工作时,我仍然能相对胜任的事。 我上过一堆政治学课程,差点成为该专业的学生,但在凌晨一点,当我还差 250 页就完成 500 页的阅读作业时,我已经睡着了。但是当我做一个 16 小时的编程作业时,我的爬虫大脑仍然让我在 VT100 上用 Emacs 编程。^(4) 我当时想,‘我最好还是选这个专业,因为我能顺利毕业。’”
他继续深造计算机科学,最终获得了硕士学位,并留在斯坦福大学担任讲师,开发一些本科课程,旨在让学生进入计算机科学的门槛不再像他当年那么高(Mike 所在的那一年,斯坦福大学才首次提供计算机科学学位)。“我在斯坦福的使命就是尽量让那些跟随我脚步的人,少走一些我曾经走过的弯路。斯坦福基本上把所有研究生课程的难度减去 100 分,然后就说‘现在你有了一门本科课程’。他们都假设你已经接受过计算机科学教育,现在只需要学一点关于编译器或自动机的知识。”
Mike 离开学术界后曾在 Apple 工作,1996 年加入 WebTV,在那里与许多未来的 Android 工程师一起工作。WebTV 在 1997 年被微软收购,Mike 继续在那里工作了几年。
2006 年初,Mike 在微软的经理 Steve Horowitz 离开,加入了 Google 的 Android 团队。“正是 Steve 的离开让我觉得是时候离开了。我在微软已经不再那么开心了,而 Steve 的离开也不会让情况变得更好。”
Steve 说:“我记得我和 Mike Cleron 谈话的时候,在我正式加入 Google 之前就告诉了他。我说,‘Mike,我必须告诉你,我刚刚接受了一个去 Google 领导 Android 收购工程的邀请。’我话还没说完,他就拿出了‘这是我的简历!’Mike 是我在 Google 的第一位员工,他在我加入后不久就加入了团队。”
Mike 在 2006 年 3 月加入 Android 后,开始了他在 Android 上的工作,参与了 UI 工具包的开发以及其他许多工作,包括启动器^(5)和系统 UI。他最终成为了被称为“框架团队”的负责人,该团队包含了 UI 工具包、框架团队^(6),以及系统 UI 的多个部分,如锁屏、启动器和通知系统。^(7)
Mike 在 2006 年 3 月加入 Android 后的第一个项目之一是重写 Joe Onorato 编写的 UI 工具包代码。关于工具包架构的分歧不断加剧;团队中的一些人认为系统的多线程特性使得代码以及使用它的应用程序变得过于复杂。
Mike 认为 UI 工具包有三种可能的方案。“最好的结果是线程安全、易于使用的多线程。第二种是单线程,但至少能理解它。最糟的情况是多线程但有 bug,因为你无法推理它。我们当时正朝着最糟的情况前进。”
Mathias Agopian 讲述了为多线程系统编写代码的过程。“当你写一个 View 时,你不能像传统方式那样写它,不能使用成员变量。^(8) 这导致了很多多线程的 bug,因为应用开发者不习惯这种方式。特别是,Chris DeSalvo^(9) 强烈反对这种多线程方式。Joe 和 Chris 总是争论不休,Chris 说这不行,根本无法工作。Mike 尝试着介入,看看能做些什么。”
Steve Horowitz 作为工程团队的主管也参与其中:“最后是我决定我们要选哪个方向,因为他们彼此无法说服对方。老实说,我认为我们对任何方向都能接受,但我必须做出决定。”
Mathias 继续说道:“Joe 直接放弃了:‘你想怎么做就怎么做。它不再属于我了。’”
之后,Mike 将 UI 工具包重写成现在的单线程形式。“这是我做过的最棘手的 CL^(10),试图以不同的方式让所有这些东西正常工作。” Mike 的代码为 Android 系统从那时起的 UI 工具包奠定了基础。^(11)
在此过程中,Mike 编写了或至少继承并增强了 Android UI 工具包的其他基本组成部分,如 View(每个 UI 类的基本构建块)、ViewGroup(视图的父容器)、ListView(可滚动、用户可以滑动的数据列表)和各种布局类(定义其子视图大小和位置的 ViewGroups)。

Mike Cleron,在 2007 年 8 月 Google 内部首次关于 Android 的技术演讲中展示(图片由 Brian Swetland 提供)
但 Android 的 UI 工具包不仅仅是视图和布局类。例如,UI 工具包还负责处理文本。
Eric Fischer 和 TextView
Mike Cleron 说,当他到达 Android 时,“Eric Fischer,就我所知,就是在某座山的石洞里发现了 TextView。TextView 已经是完成的版本。我从来没见过有人在创建 TextView,它一直都在那里。”
几年前,Eric 和 Mike Fleming 曾在 Eazel 合作,Eazel 是由一些早期 Macintosh 团队成员创办的初创公司。当 Eazel 在 2001 年解散后,Eric 和 Mike 一起去了 Danger。
像 Danger 这样的小公司吸引人的一个原因是能够参与多种不同类型的项目,而不像只支持大产品一部分的团队那样机会有限。在 Danger 工作时,Eric 涉及了从文本和国际化到构建系统,再到性能优化的各个方面。多年后,Eric 对 Android 更快的开发过程有了更深的理解。“Android 通过让 Google 而不是运营商最终决定软件中包含的内容,提供了更快、更灵活的开发承诺。”
Eric 于 2005 年 11 月加入 Google 的 Android 团队。“我为 Android 编写的第一段代码是一个 C++ 文本存储类。在我刚到的几周里,我们原以为我们会将用户界面元素编写成 C++ 类,并使用 JavaScript 绑定。”几周后,Andy 决定统一使用 Java 来开发 Android。
“一旦我们决定改用 Java,朝着建立一个可用系统的第一步就是编写 Java 标准库核心类的新实现,我做了一些这方面的工作。除了时区处理外,我相信在第一次公开发布之前,所有这些代码都被 Apache Commons 的实现所取代。”
“我接触过一些软件的其他部分,但大部分工作都集中在文本显示和编辑系统上。最早的开发硬件是带有 12 键数字键盘的‘糖果条’手机,这也是为什么有了 MultiTapKeyListener 类来处理那种痛苦而缓慢的文本输入方式。幸运的是,我们很快过渡到了带有迷你 QWERTY 键盘的 Sooner 开发硬件。”

左边是早期的“糖果条”手机,绰号“龙卷风”,团队一直使用它,直到后来的 Soonerc 设备。右边的手机是 HTC Excalibur,它在经过一些工业设计修改后(并将 Windows Mobile 操作系统替换为 Android)成为 Soonerc 的基础。(图片来源:Eric Fischer)
“从一开始,我就确保处理双向文本布局,这对于希伯来语是足够的,但对阿拉伯语就不够了。”^(13)
软件工程师往往会对自己的代码产生情感依赖,Eric 就是如此,他将这种热情体现在了他的车牌上。“我有一块加州的 EBCDIC 个性化车牌,代表了 1960 年代 IBM 的字符编码,它与 ASCII 竞争。44 楼的另一位同事则有 UNICODE 的车牌。”^(14)

在 Google 停车场,UNICODE 与 EBCDIC 作为文本标准进行较量(Eric Fischer 的车上使用的是 EBCDIC)。(图片由 Eric Fischer 提供。)
文本渲染(即绘制屏幕上显示的实际文本像素)由 Skia 在不同的层级处理,这在第十一章(“图形”)中有讨论。Skia 使用一个名为 FreeType 的开源库将字体字符渲染成位图(图像)。^(15)
Android 初期一个普遍存在的问题是性能;当时硬件能力有限,这驱动了很多软件设计和实现的决策。这些决策影响了平台和应用的代码编写方式。正如 Eric 所说,“我所有关于通用性的尝试都被必须足够快速以便在非常缓慢的早期硬件上运行的迫切性能问题所削弱。我不得不做出各种特殊的快速路径,以避免内存分配和浮点运算,尤其是在布局和绘制没有样式标记且没有变换(如省略或密码隐藏)的普通 ASCII 字符串时。”
Eric 观察到团队内部存在持续的紧张气氛,大家对如何构建系统存在分歧。“有时候感觉这个项目本不该成功。这是一个典型的‘第二系统效应’,我们中的许多人之前做过类似的事情,认为可以在没有第一次错误的情况下重新做一遍。来自 Danger 的我们想要基于 Java 类继承构建另一个用户界面工具包,但这次要确保在真实操作系统的基础上,再加上网络另一端强大的服务架构。来自 PalmSource 的人们则想要重新做他们的活动生命周期模型和进程间通信模型,但这次要做到完美。来自 Skia 的人们则想要再次做 QuickDraw GX,但这次要做到正确。我们都错了,而且错得彼此冲突。我们花了几年的时间才理清我们所有早期错误决策的后果以及它们之间的相互影响。”
Romain Guy 与 UI 工具包性能
2007 年,一位来自法国的实习生 Romain Guy 为正在成长的 UI 工具包提供了更多帮助。
Romain 在高中时成为了一名科技记者,撰写关于各种编程语言、操作系统和编码技术的文章。这份自由职业工作让他获得了当时许多流行平台和语言的经验和接触。他接触到了像 Linux、AmigaOS 和 BeOS 这样的操作系统,并且成为了 Java 的专家。
Romain 在法国的大学里攻读计算机科学专业。但那所学校更注重领导力和项目管理技能,而不是纯粹的编程,Romain 更喜欢软件开发中的编程部分。因此,他来到了硅谷。^(16)
Romain 曾在 Sun Microsystems^(17)实习,在那里他花了一年时间工作于 Swing,这是 Java 平台的 UI 工具包。
第二年,即 2007 年 4 月,Romain 回到美国,在 Google 进行实习。他加入了 Google Books 团队,并被要求参与一个与 Gmail 相关的桌面应用程序的开发。这不是一个让他感兴趣的话题,他在那个项目上只坚持了一周。他认识 Google 的许多人,比如 Bob Lee(大约在同一时间转到 Android 核心库团队)、Dick Wall(负责 Android 开发者关系)和 Cédric Beust(负责编写 Android Gmail 应用程序)。他们说服 Romain 加入 Android 团队,并说服管理层认为团队需要他。Cédric 让 Steve Horowitz 伸出援手,在 Steve 和 Andy 的帮助下,这一切得以实现。^(18) Romain 转到了 UI 工具包团队,在那里他协助 Mike Cleron 工作。
夏天结束时,Romain 飞回法国拿到学位,然后回到 Google^(19)开始了全职工作。他曾收到 Sun 和 Google 的工作邀请,但最终决定加入 Google。“Sun 给我的工作邀请比 Google 的要好得多。我加入 Android 团队是因为我喜欢那个愿景,喜欢我们做这件事的原因。加入 Google 有很多原因,但同样重要的是:这是一个可以使用一个好的开源操作系统的领域。那时,没有一个可行的东西能够大规模服务消费者。”
“Linux 已经有了一些东西。但对我来说,这个项目的机会更大,因为它专注于一个特定的产品。它不仅仅是一个操作系统的规范或理念;它还在构建产品。显然这是一个挑战,成功的可能性不大,但我们有机会实现它。实现这一点的最好方法就是帮助。”
“这实际上是早期工作如此有趣的一部分。直到大概 Gingerbread^(20),甚至可能是 ICS^(21),我们都不确定它是否成功到足以存活下来。每次发布并不完全是‘生死攸关’,但也有点像是‘做或者也许你应该小心接下来会发生什么’。”
当 Romain 于 2007 年 10 月作为全职员工加入时,初始的 SDK 就要发布了。平台上仍然有很多工作要做才能达到 1.0 版本。他开始时从使触摸输入功能化做起,这是第一个发布版本的硬性要求。
他还花了大量时间和精力使工具包代码更快。“Mike 要求我提高失效^(22) 和重新布局^(23) 的性能。直到那时,invalidate()^(24) 是非常笨的;它会向上遍历整个层级并标记所有项为无效。如果你再调用一次,它会再次向上遍历。这个过程非常慢。所以我花了很多时间添加所有这些脏标志^(25)。这带来了巨大的改善。”
但要做这些工作,他需要一个并不存在的工具。
在 Android 团队有一个悠久的传统,就是开发许多小型、单一用途的开发者工具,每个工具的工作方式都有些不同,而且它们之间并不兼容。随着时间的推移,这种情况发生了变化,大多数这些应用程序现在已经并入 Android Studio IDE 中,以便开发者能够使用一致的工具。但在早期,这些工具是由需要它们的开发者一个一个单独编写的。
在进行视图失效性能优化工作时,Romain 需要一个新工具。“我写了一个 ‘hierarchyviewer’,因为很难知道到底是哪个部分被标记为失效。所以我写了这个查看器,它可以显示视图树,并在视图被标记为脏时用不同的颜色闪烁,显示它们何时会被绘制,以及何时有 requestLayout()。^(26) 当我进行优化时,我能够看到发生了什么。它的闪烁次数减少了!”
另一个 Romain 承接的 UI 性能项目是 ListView。
ListView 是一个容器,用于包含(等一下……)一系列项。这个元素的诀窍在于,它天生对性能非常敏感。它的唯一目的是包含大量数据(图像和文本),并能够快速地滚动浏览这些项。关键是“快速”。当项进入屏幕时,UI 工具包必须创建、调整大小并放置这些新项,然后它们在滚动出屏幕的另一边时就会消失。做这些工作需要付出很多努力,而在早期硬件上,工具包无法跟上这些需求,因此用户体验……并不理想。
当 Romain 从 Mike Cleron 那里接手这个小部件时,它能够容纳、渲染并滚动项。但是它的性能远不能令人接受,因此 Romain 花费了大量的精力进行优化。出于性能考虑,避免创建对象和 UI 元素在当时的 Android 开发中是一个通用的模式,而 ListView 是一个很好的例子,能够让我们理解为什么这个模式会演变。
启动器和应用
和团队中的其他成员一样,Romain 在那些早期(以及之后)也参与了许多其他 Android 项目。除了核心的 UI 工具包职责外,他还接管了 Mike 负责的启动器应用(Mike 开始领导框架团队并承担了除代码之外的其他职责),并且在负责 Email^(27)应用的承包商离开后,他也提供了帮助。幸运的是,Romain 有相关的技术记者经验。“我曾写过关于如何实现 IMAP 协议的文章,所以我并不完全不懂。但这又是在我们做的其他所有事情之上...这有点多。”
他还帮助了其他应用程序。由于平台是新的,许多功能是为了响应应用需求而开发的。应用程序需要平台的新功能,因此他们与平台团队合作来实现这些功能。
当时应用团队的一个持续努力是性能。“满足他们的需求很重要,但同样重要的是让他们理解事物的成本。这就是为什么 HierarchyViewer 出现的原因,因为应用程序创建了太多的视图。视图层次结构对于我们的设备来说太昂贵了。这是一个向他们展示‘你们创建的这个庞大树形结构,给我们带来了很高的成本’的方式。尽管我们做了所有的优化,但这依然是非常昂贵的。所以它帮助他们了解如何优化代码。这也是我想出merge标签、include标签和viewstub标签的原因,^(28)帮助他们完成需求的同时,也能重新夺回一些性能。”
清单密度
在 1.0 版本发布后,仍然有很多工作要做,以便将平台发展到团队最初设想的状态。一个早期开始但在 1.0 时未完全实现的项目是对不同屏幕密度的支持,这在第十三章(“框架”)的资源部分中有所描述。1.0 之后,Romain 接管了 Dianne 早期开始的工作,并在 2009 年秋季的 Eclair 版本发布时完成了它。^(29)
屏幕密度直接影响该屏幕上图像的质量;高密度屏幕可以在相同的空间内呈现更多信息,从而产生更清晰、更好的图像。近年来,高密度屏幕导致了手机和笔记本显示器质量的提升。高密度的摄像头传感器也带来了更高质量的照片,因为这些传感器拍摄的图像的百万像素数大幅增加。^(30)
最初的 G1 设备,以及直到 Droid 发布之前的所有其他 Android 设备,屏幕密度为 160 像素每英寸(PPI),这意味着每英寸的屏幕空间中,垂直和水平方向上都有 160 个不同的颜色值。Droid 的屏幕密度为 265 PPI。更高的密度意味着可以表示更多的信息,从而带来例如更平滑的曲线和文字,或者具有更多细节的图像。但开发者需要一种方式来定义他们的 UI,以便利用这些密度变化。
Dianne 和随后 Romain 实现的系统,允许开发者在不依赖设备上像素实际大小的情况下,使用 dp(密度无关像素)来定义他们的 UI。然后该系统会根据应用程序运行设备的实际屏幕密度适当调整这些 UI。处理屏幕密度的这一机制,以及资源系统中基于密度提供不同资源的相关功能和整个 UI 布局系统,这些都是 Android 发展过程中至关重要的。随着制造商开始为其客户推出各种不同格式的设备,Android 从一个仅在一种设备类型(G1 及其后续设备,具有相同的大小和密度)上运行的平台,转变为一个充满各种屏幕大小和密度的世界。
工具包性能
团队所称的 UI 工具包由许多部分组成,因为它基本上是整个框架的视觉部分。真正定义那个时期团队工作(Joe、Mike、Eric、Romain 和其他人)的,是制定工具包 API 和核心功能,然后专注于性能、性能、再性能。^(31) Android 的 UI 基本上是用户所看到的一切,因此这个平台前沿部分的性能更加重要,因为那里的问题是非常明显的。所以团队不断地优化……并在某种程度上,至今仍在优化。
第十五章:系统 UI 和启动器
Android 系统 UI 是用户在屏幕上与应用外部的所有视觉元素交互的集合,包括导航栏、通知面板、状态栏、锁屏和启动器等元素。
在团队的早期,所有这些工作都发生在整体框架团队中,这个团队只有少数几个人。像状态栏、锁屏和启动器这样的功能都是由编写核心框架和 UI 工具包代码的人来完成的^(1)。这种处理方式非常高效,因为编写这些功能的人同时也在编写所需的系统平台功能,因此他们能够在问题的两面都实现所需的内容。另一方面,这也意味着他们都非常忙碌。
启动器
在 2008 年 1.0 版本发布之前,启动器(负责查看和启动应用的主屏幕应用)仅仅是 UI 工具包的另一个实现细节。UI 工具包团队的原始开发者 Mike Cleron 在将其交给 Romain Guy 之前一直在做启动器的工作。Romain 在接手后继续拥有并改进这个应用,直到多个版本发布^(2),同时还负责其他 UI 工具包的工作。
Romain 在启动器(以及整个系统)的一个持续项目中,专注于性能优化。Romain 记得 Steve Horowitz 给他的一个限制:“启动器需要在半秒内冷启动^(3)。启动器必须查看每个 apk^(4) 并加载图标和字符串,因此涉及大量多线程代码、批处理和延迟更新 UI 线程。”
Romain 还不断为启动器添加新功能,例如用于组织应用图标的文件夹、应用小部件和快捷方式(主屏幕上的图标),以及主屏幕壁纸背景和页面之间的视差效果。
后来,为了 Nexus One 的发布,Andy Rubin 希望能够呈现一些视觉上令人兴奋的效果。Joe Onorato 解释道:“对于 Eclair,Rubin 想要一些炫酷的东西。”Andy 对具体细节没有过多要求;Joe 记得他说:“做点酷的东西。”在这两个月的时间里,他们利用新设备的 3D 能力写了一个新的启动器。“GL 刚开始变得足够稳定,所以我们做了那个 3D 启动器。”
3D 启动器是所有应用屏幕中的一种特殊效果,持续了几个版本。用户看到的是一个普通的 2D 应用网格,但当他们上下滚动列表时,顶部和底部边缘会像星际大战的开场文字效果一样渐隐到远处。这个效果既微妙又强大,暗示了系统背后的 3D 功能(以及系统中可能包含的大量应用),同时又不显得过于张扬或难以操作。

Nexus One 的所有应用屏幕有一个 3D 效果,显示应用列表的顶部和底部滚动消失在远处。
通知
几年前,在智能手机出现之前,我经常错过或者迟到参加各种会议。我在电脑上使用一个日历应用,但它更擅长告诉我错过了哪些约会,而不是提醒我即将错过的约会。我记得曾经希望能有一种方式,能实时提醒我这些事件,这样我就不会再错过它们了。^(5)
这种将数字数据与及时更新连接起来的方式,最终通过智能手机上的通知得以实现。当然,这些更新远远超出了日历事件,还包括电子邮件、短信以及来自手机上各种应用和服务的海量更新。
Android 自始至终的一个独特且强大的功能,就是其通知系统,能够在用户没有使用应用时,提醒用户其安装应用中的信息。
在智能手机出现之前,通知功能要简单得多(也没那么有用)。早期的数据设备,如 Palm Pilot PDA,就有日历和闹钟应用中的提醒功能。用户可以配置这些应用播放声音、显示对话框或点亮 LED 灯。因此,这种提醒仅限于用户想到要输入的内容。设备上的所有数据都是由用户创建并同步的;没有信息会从空中传送到设备上。但一旦设备开始连接到互联网,新信息(包括电子邮件、消息,甚至新的日历约会)就可以异步地传送到设备上,用户必须被告知。因此,通知的需求和解决方案应运而生。Dan Sandler,2009 年加入 Android 并领导系统 UI 团队,曾说:“Danger Hiptop/Sidekick 设备在用户提醒的艺术上迈出了谨慎的一步,它在滚轮下方有一个彩虹通知灯,可用于短信和新电子邮件。Android 接过了这个接力棒,并把它做得非常非常好。”
应用程序与操作系统之间一直存在紧张关系。每个应用程序都认为自己是用户生活中最重要的东西,因此用户显然希望随时了解该应用程序的所有信息。与此同时,用户可能会感到惊讶和烦恼,因为他们刚安装的游戏发来了一个通知,告诉他们有一个新关卡可以玩。多年来,系统 UI 团队的工作之一就是为应用程序设定限制,并为用户提供工具,以便用户能够静音那些话多的应用程序。事实上,操作系统本身的部分工作正如 Dan 所解释的那样,“就是为应用程序提供限制。通常这与设备上的共享资源有关,比如文件、CPU 时间和网络。对于通知来说,Android 将用户的注意力添加到了操作系统调解的资源集合中。”
Dianne Hackborn 实现了第一个通知系统;图标出现在屏幕顶部的状态栏中,提醒用户有其他应用程序中的信息。随后,Dianne 和 Joe Onorato 共同开发了通知面板,用户可以从屏幕顶部下拉该面板以显示更多通知信息。用户可以点击面板中的某个项目,从而启动该应用程序,查看新邮件、阅读新短信等等。Joe 解释道:“[Dianne] 做了第一个下拉。但是我花了很多时间让它的物理效果正常工作。”^(6)
Ed Heyl 说:“我记得 Joe 在周末不停地工作,终于弄好了。他在办公室里走来走去,向大家展示,‘看,这个怎么样?看,你只需这样做,拉下来,它就会显示内容,然后就消失。’”

这就是早期 Android 版本中通知的样子。通知栏从屏幕顶部下拉,向用户展示来自所有应用程序的当前警报。
从第一天起,通知就被认为是 Android 区别于其他智能手机平台的一个重要特征。在《The Verge》的文章《Android:十年视觉历史》中^(7),这样写道:“几乎普遍认为,Android 在第一天就做对了通知系统。iOS 要等到三年后才推出一个有效的设计,能够有效地整理来自用户日益增多的移动应用程序的消息和警报。秘密在于 G1 独特的状态栏,可以向下拖动,显示所有通知,形成一个单一列表:短信、语音邮件、闹钟等。这个基本概念(以更精致的形式)延续到今天最新版本的 Android。”
动态壁纸
Android 1.0 推出时包含了一个名为Wallpapers的功能,允许用户选择一张图片作为主屏幕的背景。壁纸是展示和个性化智能手机大屏幕的好方式。
但 Andy 希望为 Nexus One 带来一些新的和特别的东西,这款手机将与 Eclair 2.1 版本一起在 2010 年 1 月发布。他要求开发一个名为Live Wallpapers的功能。既然智能手机不仅拥有大屏幕,而且屏幕后面还有强大的计算机,那么利用计算机来实现动感十足的图形体验,岂不是很好?
所以 Andy 要求框架团队实现这一功能。Dianne Hackborn 和 Joe Onorato 负责底层系统的开发,而 Romain 等人则负责实际的壁纸设计,制定整体外观,并为第一组壁纸确定功能。
他们只有五周的时间来完成这项工作。
Andy 最初要求这些壁纸使用 Processing 图形渲染系统实现。这在功能上是一个很棒的主意,但当 Romain 在 Android 上实现时,他发现这个方法对于手机来说速度不够快。由于动画速率只有每秒一帧,壁纸更像是“死”而不是“活”。因此,Romain 找到了一种不同的方式使它们能够运行。
Jason Sams(团队中的一位图形工程师,曾与 Mathias、Dianne、Joe 等人一起在 Be 和 PalmSource 工作)当时正在开发一个名为 RenderScript 的低级图形系统,该系统允许应用程序利用 CPU 和 GPU 快速绘制图形。Romain 使用 RenderScript 实现了需要流畅动画的壁纸,并最终为发布编写了以下四款壁纸:
-
Grass,展示了草叶在天空背景下轻轻摇曳,背景的颜色会根据手机所在位置的时间变化。
-
Leaves,展示了树叶在水面上飘落,形成涟漪。这是团队的共同努力,Mike Cleron 将一个由 Mathias Agopian(或者是 Jason Sams)编写的涟漪效果整合进壁纸中,并加入了他自己拍摄的^(8)来自他庭院中日本枫树的叶子照片。
-
Galaxy,展示了一个“3D”^(9)的宇宙视图,庞大的星空围绕中心旋转。
-
Polar Clock,以更具视觉趣味的方式显示时间。

四款随 Nexus One 发布的 Live Wallpapers:Particles、Galaxy、Grass 和 Leaves(图片来源:Android 开发者博客,2010 年 2 月 5 日)
除了这些壁纸外,Mike Cleron 编写了一个名为 Particles 的壁纸,Marco Nelissen(负责平台音频的开发人员)编写了三款壁纸,其中包括两个声音可视化器。
在五周的周期结束时,团队完成了一个完全功能化的动态壁纸系统,包括一个 API,外部开发者可以使用这个 API 来编写自己的壁纸。遗憾的是,Romain 在这五周期间只发明、设计、原型和实现了四个壁纸,最终团队发布的设备壁纸数量少于 Andy 所要求的十个。
Android 的面孔
Android 的系统 UI 提供了图形化的功能,让用户能够控制他们的设备。从登录、及时通知、到浏览界面、再到启动应用程序,系统 UI 是用户在设备上交互的第一个类似应用的界面。它使用户能够获取所需的功能和信息,这正是智能手机的核心所在。

Dan Sandler 给我发了这张图,说:“在我多次将系统 UI 描述为‘Android 的面孔’之后,我创造了这个非官方的 logo... 这让大多数团队成员都感到震惊。”
第十六章:设计
设计就是一切。设计就是人们如何看待一个产品,使用产品时的感受。它是某个东西成功和失败的原因之一。
—Irina Blok
Irina Blok 和 Android 吉祥物
Android 操作系统最具辨识度的方面之一就是绿色机器人吉祥物,由 Irina Blok 设计:

尽管这个标志现在已经成为全球 Android 的象征,但最初只是为开发者设计的。Irina 说:“我们的目标是激发开发者社区的兴奋感,创造出类似 Linux 企鹅的东西。”
这个设计项目没有太多的约束。Android 团队来找 Irina 的内部品牌团队并提出了请求。他们说产品的名字是 Android,并且希望有一个引人注目的发布故事。他们建议将其设计得像人类,并希望设计能够激发开发者的兴趣。
Irina 花了大约一周时间提出各种想法,才提交了最终设计。

Irina 在创作最终 bugdroid 图像(如右侧第二排最右端的图片;图片由 Irina Blok 提供)之前制作的一系列草图。
请注意,草图中的黑色标志并非“黑色”,它们实际上是无色的;黑色只是她在早期形状和想法迭代时使用的中性色。你可以看到许多设计中都有 Android 的字母 A(尽管不是最终版本)。你也可以看到早期设计中标志的黑色版本,位于底部中央。那接近设计的最终结果(加上了两根天线),但 Irina 记得这是她最初的一个想法。
最终设计中一个重要的元素就是形状本身。“这个标志的灵感来自一个国际符号。它是一个非常简单的人类符号。我尝试为 Android 想出一个类似的符号。” Irina 曾在其他品牌项目中使用过象形符号的概念,这些符号之所以有力,是因为“人们如何看待象形符号和标志,以及它们如何在没有语言的情况下进行交流。它们如此简单,能够跨越所有文化进行交流。”
Irina 还追求简洁:“因为这个标志是作为蓝图设计的,所以形状本身不能过于复杂。”
蓝图指的是最终设计的另一个方面:它被发布为开源,鼓励开发者使用并创造基于这个主题的变体:“它可以有不同的装饰。这就是这个标志系统的含义。”
关于吉祥物发布的一些元素使她的蓝图系统得以实现。其中之一是 bugdroid^(1) 被明确授权用于再利用,采用了 Creative Commons 许可证。在 Android 品牌指南网站上写道:“绿色的 Android 机器人可以复制和/或修改,只要包括以下 Creative Commons 署名行…”
这个许可赋予任何人使用和修改机器人的权利。但如果它只是一个小小的 JPEG 文件,便不会产生有趣的变化。这就是战略的第二部分开始发挥作用的地方:标志以多种文件格式发布,这些格式便于重新设计。首先,有一个高分辨率版本的 PNG 格式,带有透明背景。但如果你真的想修改图像,你会需要其他矢量格式(EPS、SVG 和 AI),这些格式可以让你直接处理机器人的几何形状。
让机器人自由可用是一次革命性的举措。伊琳娜谈到了更传统的品牌塑造方式:“身份体现在品牌指南中,那是一本内容非常庞大的书,里面有很多限制:‘这是标志周围的清晰空间,这里是颜色...’ 标志是神圣的。而这完全摧毁了传统观念。” 这个标志的这一方面并不是来自安卓团队,而是来自伊琳娜的品牌团队,回应安卓开源的做法:“这是我们为此提出的创意方案。作为设计师,你的工作就是传达产品的意义。这在当时是一个革命性的创意。这个并不是我们作为一个限制被赋予的;这是我们的解决方案,我认为这是这个标志最棒的地方。”
一旦机器人被释放到公共领域,它就开始超越谷歌和安卓的范围。“这个标志作为一个系统发布,它开始拥有了自己的生命。它开始有了维度,你可以看到雕塑。它几乎就像是生下一个孩子然后看着这个孩子成长。它开始迈出第一步,然后开始说话。等它走了出去,我从远处看着它成长。”
一旦外部社区接手了机器人,它便超越了最初面向开发者的目标受众:“它最初只是一个面向开发者的发布,原本并不打算成为面向消费者的标志。这是一个小项目,专注于开发者。但它变得如此受欢迎,以至于它变得越来越大,最终发展成了面向消费者的标志。”
衡量任何产品品牌的有效性可能是困难的。“有时候你根本无法衡量品牌的影响力。品牌赋予了产品个性,并激发了兴奋感。因为我们都是人类,这很情绪化,它有助于讲述故事,并与品牌建立联系。这也激励了开发者开发更多的东西,同时也激发了消费者的热情。”
“设计就是一切。设计是人们如何看待一个产品,以及他们在使用产品时的感受。这是某些东西成功和失败的原因之一。”
“当时,你并不会考虑这些事情——你只是在完成任务。所以这非常直观。你不会为标志做用户研究:你只会去完成它。”
获得绿灯
那么,最初 logo 中标志性的绿色呢?机器人的变体有各种颜色,但绿色是最初的颜色,也是与之相关的主要颜色。Irina 说:“绿色是代码的原始颜色。”
就像绿色文字显示在黑色终端屏幕上,比如 VT100,这是一种回顾早期编程的方式(也是电影黑客帝国中的场景,这些视觉效果回溯到同样的终端编码起源)。这个 logo 永远都和软件有关。
随着最终设计的完成,Irina 还提交了一些变体,激励大家进行创意尝试。

Irina 提交的机器人变体,用来激发灵感,其中许多最终出现在 Google 商城的 T 恤上(图片由 Irina Blok 提供)
“我的工作是激发灵感,并试图提出使用这个标志的指南。但不是根据我个人的理解来反复修改。因为这不是关于我,而是关于每个人。”
Jeff Yaksick 和 UI 设计
Android 用户界面的设计多年来经历了几次重大变化和几代人不断的完善,每一次努力都让其更加精致和一致。但在开始时,甚至没有一个单独的设计师,更不用说设计团队或设计理念了。
Jeff Yaksick 是最初的 Android 设计团队成员。他直到 2005 年 12 月才加入 Android 团队,那时 Android 团队在 Google 已经成立了六个月,差不多是在招聘开始加速的时期。
Jeff 的职业生涯始于 NeXT Inc.,但后来他转到 WebTV(该公司后来被微软收购),在那里他与未来的 Android 团队成员合作,包括 Chris White、Andy Rubin 和 Steve Horowitz。在共同创立 Android 后,Chris 联系了 Jeff,看看他是否有兴趣加入他们的创业公司(当时专注于相机操作系统)。但 Chris 无法保证 Android 的未来能像 Jeff 在微软的工作那样稳定,于是 Jeff 选择留在原地。然后,Google 在 2005 年 7 月收购了 Android,Jeff 于同年 12 月加入了 Android 团队。
当 Jeff 加入时,并没有太多需要设计的东西;最初的 Android 系统刚刚开始成型。所以他处理了一些基础的视觉设计,比如按钮的外观和复选框。他还参与了配色方案、渐变和字体的设计。
“其中一件最早的事情就是:我们用什么字体?我看了当时所有开源字体的资料。我找到的原始字体不够广泛,无法满足 Google 想要全球化的需求。^(2) 所以我和 Ascender 字体工作室合作。我帮助艺术指导了‘Droid’字体的设计,这是系统字体。”

设计草图和最终版的 Droid 字体(图片由 Steve Matteson 提供)
最终,当德国·鲍尔(German Bauer)于 2006 年 9 月加入时,Jeff 得到了一些帮助。Jeff 和德国一起处理了广泛的设计任务,从 UI 控件的外观到启动器,再到邮件和浏览器应用程序的设计。
最终,由于首个版本发布需要大量设计工作,Andy 与瑞典的 UX 设计公司 The Astonishing Tribe(TAT)签订了合同。TAT 设计了系统的整体外观和随 G1 发布的核心体验。^(3) Jeff 和 German 继续协助处理各种应用程序,如设置,并为系统完善了小部件集(按钮、复选框和其他 UI 元素)。当 TAT 的合同到期时,他们也接手了 TAT 的所有工作。
在 1.0 发布前的紧张时刻,有一股疯狂的压力去重新实现手机 UI。由于必须符合一些法律约束,手机界面外观和功能必须做出一些调整,这需要大量的重新设计工作,而时间却所剩无几。“我们拼尽全力,做了巨大的努力去重新设计手机体验,以便能够真正发布一款手机。我设计了这种带有渐变色的暗主题 UI:连接时为绿色,挂断时为红色。接近发布时,在我们发货前,Andy Rubin、我和 Sergey Brin 进行了一次审查。Brin 对速度非常挑剔,他说,‘为什么需要渐变色?它们消耗更多的处理能力。’我想他会更喜欢屏幕上有大按钮,没什么特别的。我从微软来到 Google,还是有点新,我并不完全了解 Sergey Brin 和 Larry Page 其实是掌控全局的。所以,我对 Sergey 有点带刺。”
Bob Lee 也提到了创始人与设计师之间的这种动态:“我们刚开始时,Larry 和 Sergey,可能是 Sergey,坚持认为不需要动画^(4),因为那是浪费时间。从现在看手机... 这也可以解释为什么 Android 一开始显得更加简朴。”
在 1.0 发布之后,仍有很多工作要做,因为系统不断发展。Jeff 开始着手早期的软件键盘体验,这是 1.0 之后的新功能,因为 G1 在 1.0 时只使用硬件键盘。设计团队在 1.0 之后也开始壮大,加入了更多的设计师和团队领导。
玩具
Jeff 还帮助处理了一件事,那就是 Android 玩具。
Jeff 在接近 1.0 的早期就开始对城市塑料^(5)玩具产生兴趣。他有了制作一个 Android 玩具的想法。Android 工程师 Dave Bort 与 Andrew Bell 是朋友,后者经营着 Dead Zebra 艺术工作室。^(6) Jeff 向 Andrew 发送了一些他的想法,他们与 Dave 和 Dan Morrill(Android 开发者关系团队成员)合作,让这个想法成真。

Jeff 向 Andy 发送的原始效果图,提议制作一系列 Android 小玩偶(图片由 Jeff Yaksick 提供)
从那个最初的玩具开始,逐渐发展出了一个持续的 Android 收藏玩具系列。定期(几乎每年)推出一套新的设计(然后迅速售罄)。Jeff 为这些设计贡献了三款:Noogler、Racer 和 Mecha。

Jeff 设计的 Racer 小雕像(右侧),与经典的 Bugdroid 一同展示(图片由 Andrew Bell 提供)

Racer 小雕像的设计图(图片由 Andrew Bell 提供)

Jeff 设计的 Noogler 小雕像。“Noogler”是谷歌用来称呼新加入公司的人的术语(如“新谷歌员工”)。小雕像上的帽子类似于所有 Noogler 在谷歌第一周获赠的帽子。(图片由 Andrew Bell 提供。)
Jeff 参与设计的另一件小雕像略有不同:第一座草坪雕像。在接近 1.0 版本发布时,Andy 决定在谷歌校园的 Android 大楼前放置一座雕像。Andy 认识一个制作泡沫雕像的人:Giovanni Calabrese,他是 Themendous 公司的老板。他把 Jeff 介绍给了 Giovanni,Jeff 发送了一些设计稿,他们完成了这件事。最初,Andy 要求一个比现实情况中可能的更大的雕像,但考虑到从工作室运输的现实情况,他们缩小了尺寸以便顺利进行。^(7)

最初的 Android 雕像(昵称为“bigdroid”),2008 年 10 月,与 Andy McFadden 一起展示,用于比例显示,雕像多年来一直矗立在 44 号楼前的草坪上,那里是大部分初始团队的工作地点。(图片由 Romain Guy 提供。)
Jeff 回顾了 Android 和谷歌的设计演变:“当我加入谷歌时,它可能类似于微软早期,当他们开始制作 Windows 95 和 Vista 时。那时,设计开始变得重要起来。NeXT、微软、谷歌——它们都是工程为基础的公司。说服工程人员这些东西很重要一直是个挑战。我认为苹果绝对帮助推动了这一进程:设计很重要。”
第十七章:Android 浏览器
要理解 Android 浏览器应用程序,首先需要了解 Android 之前的网络浏览状态。
Google 一直非常关注网络技术。从一开始,Google 的主要任务就是提供搜索查询的结果。因此,广泛投资于像浏览器这样的网络技术是合乎逻辑的;提供结果的工具越好,Google 为这些结果提供的体验就越好。尤其是在 2000 年代初期,浏览器公司所推动的网络浏览状态对 Google 来说至关重要。
伟大的浏览器战争
在互联网初期,Netscape 浏览器是当时的王者;桌面用户会下载并使用 Netscape,因为那时就是上网的方式。但是微软推出了自己的浏览器 Internet Explorer(IE),最终将其与 Windows 捆绑在一起。捆绑 IE 几乎保证了微软的浏览器会成为大多数用户的默认浏览器,因为它作为操作系统的一部分预装,而且(当时)足够好。Internet Explorer 甚至在 Apple 推出自己 Safari 浏览器之前,曾是 MacOS 上的默认浏览器,直到 2003 年。
Netscape 和 IE 之间的紧张关系成为了维基百科幽默地(尽管是正确的)称之为“第一次浏览器战争”的核心,这场战争导致了诉讼,并最终使 Netscape 死亡,Internet Explorer^(1) 接管了全球市场。
在此期间,微软实际上处于决定人们如何访问网络的位置,因为 IE 越来越成为他们进入网络的大门。
为了确保所有用户都能访问到出色的网络体验,包括正在引入的新网络技术,Google 开始资助浏览器开发。最初,Google 与 Mozilla 基金会合作,支持 Firefox 浏览器。特别是,Google 通过实施或协助一些改进措施,贡献了工程资源,包括性能提升、内联拼写检查、软件更新系统以及浏览器扩展等。Google 并没有像微软或苹果那样拥有可以捆绑浏览器的操作系统,但它可以提供一个更好的浏览器替代方案,并鼓励人们切换使用。
Google 在 2006 年创建 Chrome 浏览器时决定进一步推动这种方法。它从头开始(使用开源的 WebKit 代码库),构建了一个全新的浏览器,以实现 Google 想让用户体验的网络效果。Google 专注于添加现代化的网络功能,并提高浏览速度。^(2) Google 还默认在 Chrome 中捆绑了对其搜索引擎的访问;在浏览器的地址栏中输入搜索查询会显示 google.com 上的搜索结果,就像用户访问了 Google 的主页并在搜索栏中输入一样。
Chrome 浏览器于 2008 年 9 月推出,并最终获得了不错的市场反响。用户回到了下载浏览器应用程序的世界,而不是仅仅使用随桌面电脑预装的浏览器。
Android 需要一个浏览器
Android 对移动浏览器的需求与谷歌对桌面浏览器的需求不同。
与桌面浏览器的情况不同,Android 平台是从零开始构建的。他们不需要更好的浏览器;他们需要任何浏览器。具体来说,他们需要一个能够让用户在手机上查看网站的应用,就像在桌面电脑上那样。他们还需要一种将网页内容直接集成到其他应用中的方式,因为他们意识到移动应用和网页内容之间的界限正在模糊。
例如,一个移动应用程序可能想要向用户展示来自网站的内容。有时候,直接在应用中展示内容比将用户重定向到浏览器应用程序更好。这样的动态不仅提供了更加流畅的体验,而且确保用户不会永远离开应用程序。而且,许多开发者更熟悉 HTML 和 JavaScript,这些是网络语言,因此为他们提供在移动应用中创建网页内容的方式,扩大了开发者群体,也使人们能够更快地创建基础的 Android 应用程序。
Android 团队创建了 WebView 来满足这一需求。WebView 是一个可以嵌入到更大的 Android 应用中的网页查看器。它与 Android 浏览器一同开发,因为浏览器本质上是一个被额外控制和 UI 包围的 WebView。
但一开始,这些都不存在,平台需要所有这些功能。所以他们需要一个开发者来把这些东西整合起来。幸运的是,他们中的许多人曾与 Danger 公司的一位工程师合作过:黄伟。
黄伟和 Android 浏览器
黄伟有多年的开发网页浏览器和软件的经验。但那段经历并不是从童年开始的。
当黄伟十二岁时,他参加了一门编程课程。但二进制数学的原理让他难以理解,他放弃了。当母亲给他展示一篇关于计算机是未来的文章时,黄伟坚信他刚刚毁了自己的一生。
许多年后,在高中时,他再次尝试编程,这一次取得了更多成功。他最终获得了电气工程学位,然后在研究生院爱上了计算机图形学编程。
研究生毕业后,黄伟在微软找到了工作,与其他未来的 Android 团队成员一起工作,包括 Steve Horowitz。黄伟为 WebTV 和 IPTV 产品开发了网页浏览器,学习了在非桌面屏幕上渲染网页内容所需的技术。但最终,他想做些其他的事情。“帮助人们看更多电视似乎并不是一件特别崇高的事情。”
史蒂夫把魏介绍给了 Danger 公司的 Andy Rubin。那时,Danger 还没有转型做手机,他们仍在开发“坚果黄油”数据交换设备,而魏对这个项目并不感兴趣。“我不确定这个设备能否卖得出去。商业模式似乎有些薄弱。所以我决定去 AvantGo。我觉得那里更有可能成功。”
“这不是一个非常明智的决定。”
AvantGo 在魏加入后不久,于 2000 年 9 月进行了首次公开募股(IPO),恰逢互联网泡沫开始破裂之时。AvantGo 像许多其他初创公司一样,遭遇了困境。“我的时机真的很糟糕。我赶上了那个泡沫的末期,然后一切都崩溃了。”此外,工作和文化也不是魏所想要的,因此他开始寻找其他机会。“我联系了 Andy。在风险投资的支持下,他们决定做手机。这听起来更令人兴奋,所以我在 2001 年 1 月加入了 Danger。”
在 Danger,魏再次在做一个网页浏览器。Danger 的手机功能非常有限,因此与浏览器在桌面电脑上运行的方式(或后来在 Android 手机上的运行方式)不同。Danger 在服务器上运行一个无头^(3)浏览器。当用户在 Danger 手机上的浏览器应用中打开网页时,页面会在服务器上渲染。服务器然后会重新格式化该页面,并将简化版发送到手机上。这种方法没有为用户提供完整的网页功能,因为缺少网页的动态功能。但他们获得的网页浏览体验,接近他们在桌面电脑上熟悉的体验,远远比他们在其他手机上的体验要丰富。
魏在 Danger 工作了四年,为几款 Danger 的 Hiptop 设备发布了浏览器。最终,他准备迎接新的挑战,希望是另一家初创公司。来自 Danger 的朋友 Chris DeSalvo 建议他去找 Andy Rubin,后者已经离开了 Danger,正在经营一个名为 Android 的隐秘初创公司。魏当天晚上通过即时消息联系了 Andy,Andy 问他是否想加入。
“他说,‘哦,顺便说一下,我们要被 Google 收购了。’”
“我当时有种沉重的感觉,因为我正在寻找一家初创公司。这并不是一家初创公司。我得好好考虑一下。当时我对 Google 并不熟悉。我以为它只是一个搜索公司。我当时并没有完全理解 Google 的雄心壮志。但 Andy 所传达的兴奋感仍然说服我加入了。”
魏于 2005 年 9 月加入了 Google 的 Android 团队,成为第二位加入的收购后员工,仅次于他的朋友 Chris。
魏的第一个项目是……又一个浏览器。但在他能够编写浏览器应用之前,还有很多工作要做,因为作为一个平台,Android 实际上还不存在。“我下载了代码库。我有点惊讶。你们怎么把这家公司卖给 Google,只不过是一些 JavaScript 代码?”
第一个任务是为浏览器选择一个起点。到 Android 开始时,已经有多个开源浏览器引擎可以作为起点,因此 Wei 不必从头编写整个应用程序。WebKit 是基于另一个开源浏览器项目 KHTML,由 Apple 启动,并成为 Apple Safari 浏览器的基础。“我非常喜欢这个代码库,所以对我来说这不需要多想。”
Wei 开始基于 WebKit 引擎构建浏览器。与此同时,浏览器团队也在壮大,首先是管理层:Rich Miner。
Rich Miner 构建团队
Rich Miner,后来帮助建立了许多 Android 早期的企业合作伙伴关系,他既懂商业又懂技术。他在小学时接触到了编程,当时班级通过打孔卡学习 Fortran。“直到今天,我仍然惊讶于我们应用程序中占用的内存量,我时常想起自己当时如何挤进修改后的代码。”
Rich 在大学一年级时首次展示了他将商业与工程结合的技能。他为自己的 Commodore 64 计算机编写了一款游戏,并在一些朋友的帮助下将其出售。“我和室友们在宿舍里有一套磁带复制系统,自己包装游戏。我会四处走动,亲自将游戏卖给当地的 Commodore 经销商。我还在一本 Commodore 杂志上投放了广告,并通过电子邮件处理订单。”
Rich 曾就读于马萨诸塞大学洛厄尔分校,学习物理学,但很快转了专业。“我坚持了半个学期后意识到我应该学习计算机科学,我的成绩也开始反映出这一点。”
在本科学习期间,Rich 成为学校生产力提升中心的负责人之一,成功为该中心争取到来自 Digital、IBM 和 Apollo 等公司的数百万美元资助。在研究生阶段,他继续在实验室工作,并成为联合主任,同时攻读博士学位。实验室孵化的一个项目促使 Rich 在 1990 年 12 月创办了 Wildfire Communications 公司。Wildfire 提供了包括基于语音的自动助手服务,能够转接电话和留言等功能。Wildfire 经营了近十年,直到被法国电信公司 Orange 收购。收购后,Rich 在剑桥创建了 Orange Labs,并担任研究主任以及新创风险基金的负责人。
在 Orange 工作期间,Rich 帮助推出了第一款 Windows Mobile 手机,并在 Orange 的网络上运行。这次经历并不愉快,因为 Microsoft 对最终设备的控制要求过高。Rich 从这个项目中得出结论,移动生态系统应该是开放的平台,而不是被平台提供商所限制的选择。
Rich Miner 是 Android 的共同创始人,并且是帮助其被收购的商业团队成员。但在加入谷歌后,他开始寻找帮助日益壮大的工程团队的方法。他接受了管理初期浏览器项目的工作。
Rich 在 Android 被收购后留在波士顿地区,远离位于山景城的团队其他成员。谷歌在波士顿市中心只有一个小型的销售办公室,于是 Rich 向谷歌高层 Eric Schmidt(首席执行官)和 Alan Eustace(工程副总裁)游说,希望能在波士顿开设一个工程师办事处。这是一个艰难的推销。“Eric 对东海岸的经历不太好。Sun Microsystems 在他掌舵时曾在这里开设过一个工程办公室,但他们将其设在了城市的边缘。我不得不说服他,靠近大学的地方能够吸引到最优秀的人才。我们可以建立一个伟大的办公室。”
Rich 说服了谷歌高层,谷歌在剑桥市中心开设了一个办公室,就在 MIT 街对面。^(5) Rich 在那里招聘了第一批工程师,其中包括一些 Android 团队的成员。
Rich 招募了他在 Orange Labs 的前同事 Alan Blount 加入浏览器团队。与此同时,在山景城,Wei 为团队找到了另一位工程师:Grace Kloba。几年前,当他在 Adobe 工作时,Wei 曾说服 Grace 放弃她的博士学业并加入他。这次,他再次说服她离开 Adobe。
Grace Kloba、WebView 和 Android 浏览器
Grace 从母亲那里第一次学会编程,她母亲是中国第一代接受计算机教育的人,时间大约在 1970 年代末。她的母亲从学生迅速转为教师;在参加了一个为期三个月的强化编程课程后,她回到大学负责计算机实验室并教授编程语言课程。在这个过程中,Grace 学到了 BASIC 和 Fortran 编程的一些知识。
Grace 后来根据图像处理实验室的优良设施选择了她的本科专业。这一选择效果很好,帮助她打下了计算机科学和电气工程的基础。大学毕业后,她来到美国斯坦福大学攻读计算机图形学的研究生课程。她在斯坦福的同学中有 Wei,而十年前他们曾在中国一起上学。
Grace 通过了博士资格考试,正在寻找论文题目时,Wei 联系了她,提供了 Adobe 的机会。Grace 离开了研究生院,加入了 Adobe 工作了几年。之后,2006 年,Wei(那时已在谷歌)再次联系了她,Grace 进行面试后收到了谷歌的工作邀请。
Wei 希望 Grace 和他一起加入浏览器团队,但他必须说服 Steve。Android 招募了在嵌入式系统、移动设备和操作系统平台方面有经验的领域专家,而 Grace 并没有这种经验。但 Wei 向 Steve 保证一切都会顺利进行,Grace 于 2006 年 3 月加入了 Android 浏览器团队。^(6)
Grace 需要解决的问题之一是如何在当时手机的小屏幕上更方便地查看网页内容。她有排版文本内容的经验,^(7) 这在她使浏览器能够在小屏幕上以合理的方式显示文本时派上了用场,尽管网页作者在编写原始 HTML 内容时设想的是更大的内容区域。
在她团队的工作期间,她还解决了浏览器和 WebView 组件中的许多其他问题。毕竟,在 Android 初期的几年里,只有少数几个人支持这一大块功能。她实现的一些功能包括多线程支持、改进的网络能力,以及常见的浏览器 UI 元素,如标签页。
还有一个最后时刻的项目,就是为了 2010 年 1 月初 Nexus One 发布,搞定捏合缩放功能的实现。Grace 在假期归来时,发现 Andy Rubin 在问实现这个功能需要多长时间。他非常希望在即将发布的这款手机上看到这个功能,发布会就定在那个月。三周后,Grace 交付了这个功能,手机也带着这项新功能发货了。
Cary Clark 和浏览器图形
Android 团队大部分成员都集中在山景城。但浏览器团队是一个显著的例外:Grace 在山景城,Wei 在西雅图,Rich 和 Alan 在波士顿。然后,Skia 团队在完成他们的图形引擎工作后,加入了浏览器团队的工作。
浏览器的绘图需求与 Android 系统的其余部分不同。渲染图形是 Skia 团队擅长的工作,因此他们负责渲染浏览器内容。例如,Cary Clark 花了大量时间让原本为桌面计算机设计的网页,在这种新型且受限的设备上能够合理显示和响应。
Cary 在加入 Android 团队之前,已经有了长时间的 2D 图形和浏览器经验。但他的编程背景更早可以追溯到 1968 年,当时他 11 岁,圣诞节收到了一个 Digi-Comp I。这个设备不像我们今天所知的计算机,而是通过塑料和金属部件来执行简单的布尔运算和数学运算,例如从零到七的计数。^(9) Cary 对这个机器非常着迷,以至于把它用坏了,并在第二年圣诞节请求得到同样的礼物。
他在 70 年代末期升级到了一台二手的 Apple II,当时他正在上大学,花了大量时间在宿舍里学习编程,拆解史蒂夫·沃兹尼亚克在 Apple II 上的 BASIC 实现,结果导致他未能顺利完成学业。后来他回到学校,完成了学位,但在此期间他已开始在一家爱好者计算机商店从事销售工作。当顾客对他们的 Apple 计算机有疑问时,Cary 会拨打地区 Apple 技术支持办公室的电话来寻求答案,但他发现工作人员根本不知道设备的实际工作原理。于是他申请并获得了这份工作。作为地区支持部门的一员,他偶尔会打电话到库比蒂诺总部,但他意识到那里的技术支持人员也不了解足够的知识,于是他大声抱怨,最终搬到了库比蒂诺,并在 Apple 总部的技术支持办公室工作。
在 Lisa^(10)和 Mac 的开发过程中,Cary 转向了管理岗位,同时仍然从事编程工作。但最终他决定全职做软件工程师:“我曾是一个糟糕的经理。”他在 Apple 工作直到 1994 年,期间参与了多项工作,其中包括领导 QuickDraw GX^(11)的开发,这是一个新的 2D 图形库,能够比 Mac 原有的 QuickDraw 库更快地绘制图形。这个项目的代号是 Skia,Cary 从一个希腊词中选取了这个名字,该词指的是在墙上绘制影子的动作。QuickDraw GX 的主要功能是绘制轮廓并填充,因此这个代号十分贴切。
Cary 最终离开了 Apple,先后在 WebTV 和被微软收购后的微软工作,他与一些未来的 Android 工程师们合作。Cary 负责 WebTV 浏览器的开发,尝试让原本为桌面计算机设计的内容在电视上合理显示和互动,电视的输入机制完全不同。后来他搬出了硅谷,前往北卡罗来纳州的查佩尔希尔,在那里为微软远程工作。在那里,他开始与 Mike Reed 交流,Mike 是他在 Apple 时认识的。Mike 将 Cary 引入 Openwave,在那里 Cary 再次从事浏览器技术的工作。然后,Mike 离开了 Openwave,创建了一个新的图形创业公司,名为 Skia,以纪念 Cary 为 QuickDraw GX 选择的代号。
当 Cary 开始参与 Android 浏览器的开发时,他面临了一些问题需要解决。例如,输入问题非常复杂,需要解决如何将键盘、方向键、轨迹球以及最终的触摸事件转换为网页上的交互。Mike 说:“第一款拥有触摸屏的设备仍然有轨迹球和箭头键。所以我们不得不在两种世界中兼顾。浏览器上更困难一些,因为有两种方法可以设置当前的关注项和焦点。你可以用手指滑动,也可以按下箭头键多次。所以这造成了一些复杂性。”
其中一个复杂的问题是如何在网页中导航链接。如果用户试图使用 D-pad 导航,需要有一种方法来跳转到“下一个”链接。所以如果用户按下 D-pad 上的右键,焦点需要移动到右侧的下一个链接。但网页并没有相对定位链接的概念,因此根据用户的输入,哪一个链接应该获得焦点并不明显。此外,Cary 还需要设计一种系统来直观地指示某个链接已获得焦点,以便用户知道当他们按下选择按钮时,会点击哪个链接。
流畅滚动是另一个难题。Mike 说:“Apple 设定了每个人都应该流畅滚动的预期。我们在第一版使用轨迹球和箭头时并没有流畅滚动。当我们滚动二十个像素时,屏幕就跳动,就像地球上所有桌面计算机一样。然后突然之间,你必须让一切都流畅滚动,无论它是手指滑动还是其他。那时我们真的下了很大功夫。Cary 发明了^(12) 图片^(13) 对象,这个在 Skia 中之前是没有的,它是一个显示列表。浏览器可以处理所有慢速的 Java 单线程内容,将其交给另一个线程,然后我们可以尽快地绘制图片,而不必与浏览器进行交互。”
另一个任务是如何让现实中的网页在内存有限的小设备上合理显示。Cary 多年前在 WebTV 产品上处理过相关问题,成功地将针对桌面计算机设计的网页显示在电视屏幕上。但他在 Android 浏览器上遇到的问题是全新的:网页上的内容实在是太多了,包括“那些疯狂长的页面,尤其是当它们被适配到手机屏幕宽度时。”
Cary 当时最喜欢的一个例子是 Wikipedia 上关于 奶酪 的页面,^(14)该页面由于某种原因非常非常长。“它的高度有好几百万像素。我们无法在数学系统中表示这么多像素,因此我们不得不想办法解决这个问题。”
当这个问题解决后,又出现了另一个问题;即使用户最终能够看到页面上的所有内容,滚动整个页面仍然需要很长时间。所以 Cary 在浏览器中实现了一个系统,能够检测到用户是否在反复滚动,并且在页面上弹出一个放大镜对象,显示整个页面的缩略图,用户可以通过它快速跳转到页面中的特定位置。
第十八章:倫敦呼叫

来自大西洋另一侧的浏览器团队也得到了促进。
谷歌的伦敦工程办公室最初是为了从事移动项目而设立的……但并非 Android 项目。伦敦的工程师们使谷歌的应用程序和服务能够在当时多种移动平台和设备上运行。在 iPhone 和 Android 推出之前(以及它们发布后的最初几年),全球有许多手机平台,谷歌希望将其应用程序提供给这些平台。
移动项目最初在山景城开始,吸引了像 Cédric Beust 这样的人才,他领导了一个团队,使 Gmail 能够在移动设备上运行。但最终,谷歌在伦敦开设了一个新办公室,负责为当时两大主流移动操作系统——Symbian 和 Windows Mobile——开发软件。
早期团队成员 Andrei Popescu^(2)谈到了为何选择伦敦来进行这项工作:“2007 年,核心的移动专业技术在欧洲,而不是美国。欧洲的 3G 技术发展早于美国。如果你看看当时开发的移动操作系统,技术中心就在欧洲。Symbian^(3)是在伦敦开发的,Series 60 和 UIQ^(4)是诺基亚和爱立信在 Symbian 之上开发的。所以谷歌做出了一个有意识的决定,将移动技术中心建立在伦敦。”
“我们在招聘方面也做得很好——伦敦是一个很棒的招聘地点。我们能够吸引来自世界各地的人才,而且欧洲有许多优秀的计算机科学学校。从地理位置上来看也很合理,”因为伦敦是距离加利福尼亚(谷歌总部所在)的主要欧洲城市之一,而且两地之间有直飞航班。
但该网站需要为移动项目寻找负责人,因此在 2007 年初,谷歌聘请了 Dave Burke。
Dave Burke 和伦敦移动团队
Dave Burke 从小就对计算机感兴趣。他将一个操纵杆、一个光电池、一只家庭投影仪的放大镜、一台录音机、一台语音合成器和一些自己写的代码结合在一起,制造了一个装置,可以向进入他房间的人发射橡皮筋。“我上瘾了。我的可怜的妹妹。”
他在本科和博士阶段学习了电气工程,之后在一家初创公司管理工程团队。到 2007 年,他决定自己想要更多的经验,而这些经验是那家小公司无法提供的,于是他加入了谷歌,领导新的移动团队。当时他想搬到硅谷,但伦敦正是当时的机会所在。^(5)
2007 年,伦敦发生了两项独立的移动项目:移动搜索和浏览器相关工作。该团队使谷歌的软件在这些领域能够在各种非 Android 设备上运行。与此同时,Dave 开始接触 Android,学习 API 并编写 Android 应用程序。
在 Dave 加入后的九个月,Android SDK 正式上线。伦敦将举办一个大型活动,Rich Miner 邀请 Dave 做一个关于 Android 的演讲,向观众介绍 SDK。于是 Dave 在众人面前进行了现场编码^(6),在八分钟内创建了一个简单的网页浏览器应用。
演讲进行得很顺利,Dave 对结果感到很满意,直到第二天。“我收到了 Andy Rubin 发来的邮件,内容是‘这个人到底是谁,为什么他要公开谈论我的项目?’”显然,Rich 还没来得及告诉 Andy,他已经邀请 Dave 做这个演讲。
Dave 说:“我和 Andy 的关系一开始非常简单。我觉得,关系只会越来越好。”
随着时间的推移,伦敦团队开始为 Android 做更多的项目。与此同时,Dave 的团队正在开发的应用最终被产品团队直接接管(例如 YouTube)。移动团队被解散,Dave 的团队进入了 Android。
Andrei Popescu 和伦敦浏览器团队
Andrei Popescu 的团队负责伦敦的移动浏览器项目。由于 Andrei 曾在诺基亚从事过类似的工作,他自然成为了该项目的首选。
在罗马尼亚布加勒斯特获得计算机科学本科学位后,Andrei 离开了祖国,前往芬兰赫尔辛基攻读硕士学位。他原本计划在拿到学位后返回罗马尼亚。那是二十多年前的事了:“我仍然在这条路上。”
在完成研究生学业后,2002 年,Andrei 在赫尔辛基的诺基亚找到了一份工作,参与了 MMS^(7)编辑器的开发。“我当时非常沮丧:我在两个国家完成了所有的学习,获得了硕士学位,但现在却在做这个小小的垃圾东西,功能有限,且是在一个当时已经显得非常古怪和难懂的 C++变种上做的系统。那时候,我没有远见去意识到,我正在从事一项将改变世界并塑造我未来几十年职业生涯的技术(移动技术)。”
幸运的是,他在诺基亚遇到了 Antti Koivisto,Antti 当时正在做一些更有趣的事情。“他正在低调地为诺基亚手机开发一个完整的网页浏览器,基于一个叫做 WebKit 的库,支持 Symbian 操作系统。”他们成功地实现了这一点,并将完整的浏览器应用发布给了大量的诺基亚用户。
在那个项目之后,Andrei 想搬到伦敦。他不在乎具体的工作内容,只想搬家。“谷歌对我来说是一种梦想。但对我而言,当时唯一的动力就是搬到伦敦。我投了数百份简历,收到了一个回复:谷歌。”
Andrei 在 2007 年 1 月加入谷歌,成为移动团队的一员。最初,他负责将 Google Maps 应用到诺基亚手机上的项目。但很快,他开始了一个名为 Lithium 的项目,计划为 Windows Mobile 开发一个完整的网页浏览器。
安德烈的团队包括本·默多克(当时是实习生^(8))、史蒂夫·布洛克和尼古拉斯·鲁阿尔。
尼古拉斯·鲁阿尔,准备起航
在法国上大学并在一家创业公司工作后,尼古拉斯开始了在威尔士的博士课程。最终,研究资助用完了,“我还需要养活自己。”于是,尼古拉斯带着博士学位申请了伦敦的谷歌,并于 2007 年 4 月加入,开始参与安德烈的锂电池项目。
锂电池是基于 WebKit 浏览器引擎构建的一个应用程序。想象一下,如果你手机上使用的浏览器不是预装的,而是需要作为一个独立的应用程序下载。原型看起来有希望,但……体积庞大。锂电池要求用户为手机下载一个非常大的(二进制文件,尤其在当时)文件。该项目最终被取消,安德烈的团队转而开始开发 Google Gears。
Google Gears 是谷歌推出的一项努力,旨在为当时的浏览器提供更丰富的功能,如本地存储和地理定位^(9)。随着 HTML5 的出现,这些功能逐渐成为浏览器的标准,Gears 最终被停用。Gears 于 2007 年首次发布在桌面平台上,安德烈的团队使其在移动浏览器上也得以运行。
最初,团队将 Gears 移植到 Windows Mobile 平台。到这个时候,当 Android SDK 发布时,已经可以明确看出,Android 平台和产品至少在某种程度上将会存在。因此,团队开始将 Gears 移植到 Android 浏览器。Gears 作为浏览器的一部分继续发布,直到 2009 年底的 Donut 版本被最终弃用;这时将这些功能直接集成到浏览器中更为合理。
在安卓初期,安卓团队以外的谷歌工程师并不能轻松地向安卓贡献代码。事实上,他们无法做到;安卓团队以外的人甚至没有权限或许可这么做^(10)。但安德烈团队的工作对安卓平台至关重要,因此他们被纳入其中。安迪授予安德烈的团队完整的源代码访问权限,使他们成为当时唯一能访问这些源代码的安卓以外的团队。
随着团队与安卓浏览器的合作越来越多,他们逐渐成为了整个浏览器团队的一部分。安德烈的团队主要专注于前瞻性的浏览器功能。例如,他们致力于创建和实施地理定位的网页标准。他们还让视频元素^(11)(HTML5 中的另一个特性)在浏览器中得以实现。
2008 年,在 Android 1.0 发布前夕,移动团队的副总裁(Vic Gundotra)解散了移动团队,包括 Dave Burke 的伦敦团队。移动项目被吸收到各个独立的产品团队中。自从开始进行移动努力以来,移动计算和设备的格局发生了剧烈变化。iPhone 自 2007 年中期发布并且很受欢迎,而 Android 也即将发布。智能手机引领着一个新世界,移动应用将变得越来越重要,公司也在将移动能力更直接地融入到其产品中。
Dave 的团队已经证明对 Android 非常成功和有用,因此在 Hiroshi Lockheimer 的帮助下,他们说服 Andy 将他们全部引入 Android 团队。他们放弃了为其他平台所做的工作,完全专注于 Android 的工程努力。
Android 和 Web 应用
Android 的浏览器和网页技术持续改进,团队也不断投入更多的努力和人力到这个项目中。2013 年,Android 浏览器(以及 WebView)被 Chrome 取代,公司决定,多个团队和项目专注于类似的技术目标可能没有意义。WebView 和浏览器仍然是移动技术栈中重要的一部分,允许用户浏览丰富的网站,也允许开发者使用网页技术编写应用程序。
第十九章:应用程序
移动应用生态系统
对于安卓用户来说,数百万个可用的应用程序在保持平台的相关性方面至关重要。毕竟,应用程序是用户在智能手机上花费最多时间的地方。
如果现在有人推出一种新的设备或平台,而没有任何应用商店(更别提一个用户密集的商店),那根本行不通。当 RIM 推出 BlackBerry 10 时,他们为智能手机推出的最终操作系统^(1),添加了一个兼容模式,允许用户安装并运行安卓应用程序。他们这样做是因为认识到,BlackBerry 的应用生态系统(尽管公司和其手机已经存在多年)无法提供安卓和 iOS 应用商店中那么广泛和多样化的应用程序。
但即使有大量的应用市场,平台上仍然必须有一组核心应用,特别是来自谷歌和苹果这样的公司,这些应用让用户能够访问他们期望从这些公司获得的服务和功能。
当安卓刚推出时,并没有其他应用的生态系统。所以安卓团队构建了随设备一起发布的核心应用集,并为用户提供了引人注目的功能。
今天,这些谷歌应用程序(Gmail、Maps、Search、YouTube 等)由拥有这些产品的团队开发。因此,不是安卓团队编写 YouTube 应用程序,而是 YouTube 部门编写核心的 YouTube 服务和基础设施、网页版应用程序、安卓应用程序,以及与更大产品相连的其他客户端应用程序。
但在早期,其他产品团队都无法完成这项工作。这些其他团队都有足够的工作要做,没时间为这个新且未经验证的平台开发应用程序。而且,安卓平台和 API 不断变化,一直到 1.0 版本发布之前也是如此。当一个成熟的产品为何要承担编写应用程序的工作和烦恼呢^(2),如果它们必须不断根据 API 变化而重新调整?
因此,安卓团队的工程师承担了编写这些初始版本核心应用程序的工作。这些是个人,而非团队,因为很少有超过一到两个人参与这些初始应用程序的开发(这些应用程序现在由更大的团队维护和开发)。例如,安卓的初始 Gmail 客户端主要由 Cédric Beust 编写,Mike Cleron 则提供了一些性能方面的帮助。
Cédric Beust 和 Gmail
我知道我们做对了事情,第一次成功地获得推送通知时。
—Cédric Beust
安卓版 Gmail 的根基来源于其他平台的版本,因为它的主要作者是 Cédric Beust。
2004 年,Cédric 加入了 Google,并且像许多有服务器端经验的新工程师一样,最终进入了广告组工作。经过一年的时间,他开始寻找新的挑战,并发现有一个小团队在研究移动技术。这个团队的工作是让 Google 的应用和服务能够在那个时代的各种移动设备上运行。Cédric 加入了这个团队,并开始了 Gmail 的开发工作。他最终组建并领导了一个约二十人的团队,开发了 J2ME 版的 Gmail 应用。
在那个时代,像今天的两个主要平台(iOS 和 Android)并不存在普及的移动“平台”。相反,当时有许多厂商特定的平台,覆盖了市场的特定细分领域,比如微软的 Windows CE 和 RIM 的 BlackBerry OS。还有 J2ME,它声称可以跨越多种设备运行,使用相同的编程语言(Java)和某种形式的 J2ME 库。因此,一个公司试图覆盖整个生态系统中的各种设备时,会发现 J2ME 的概念非常诱人。但 J2ME 的实际情况是……相当困难的。
Cédric 说:“我们开始考虑如何在 J2ME 上实现 Gmail。我们很快意识到这真的是个糟糕的主意。它几乎存在于所有设备中……但每个厂商,甚至同一个型号的设备,都有不同版本的 J2ME。它们的限制各不相同。并不是所有设备都实现了相同的配置文件。有些设备有蓝牙,其他没有。没有任何约束、合规之类的东西。任何手机都可以声称自己符合 J2ME 标准,却根本不支持我们所需要的半数功能。所以我们当时非常困扰。”
但 Cédric 的团队最终成功推出了一个版本的 Gmail,这个版本忠实于 Gmail 在网页上的核心体验,能够在这些尺寸更小、功能更受限的设备上运行。“我们在约 300 款不同的设备上推出了 J2ME 版 Gmail,并且 UI 设计也相当不错。有些设备比其他设备更麻烦,但总体来说,我们成功了。”^(3)
在 Android 被 Google 收购后不久,Andy Rubin 联系了 Cédric。作为移动 Gmail 团队的负责人,Cédric 是帮助为新兴的 Android 平台编写 Gmail 的合适人选。他当时已经有兴趣,但当 Andy 描述了这个项目的动态时,他完全被吸引了。Andy 的团队由一群底层内核专家组成,其中许多人有将受限的移动设备推向市场的经验。^(4) 他们正在创建一个基于 Java 编程语言的平台(Cédric 是这个语言的爱好者和专家),并且他们需要有编写应用程序的专业知识。“听说这些人很开放,并且我们需要用 Java 来编写,这对我来说更加有趣和吸引人。”
Cédric,像许多早期的安卓工程师一样,拥有相关的经验和观点,并且强烈希望在安卓上做对的事情。“我了解那种痛苦,并且清楚我不想再发生什么。调试 J2ME 时,你无法连接调试器,只能通过在状态栏上println()^(5)来查看自己在代码中的位置。这简直是噩梦。所以我知道我到底想修复什么。”
当他开始时,安卓上正在开发的两款应用是 Gmail 和日历。
现在,应用程序与其产品组的开发更为紧密是有道理的。但在当时,让应用由安卓团队的工程师开发对应用本身和安卓平台都非常有用。首先,平台和所有的 API 都在不断变化,应用必须能够应对这些变化。此外,在许多情况下,应用开发人员需要平台做出变更才能支持他们的需求。像 Cédric 这样的应用开发人员主要负责应用程序,但在必要时,他们也会帮助核心平台和安卓 API 的开发,特别是应用驱动的平台变化。
“我和 Mike [Cleron] 一起工作,做布局系统、视图系统,如何处理所有原始的布局 API 和算法,双遍算法。我和 Dianne [Hackborn] 以及其他人一起合作,也涉及到 Intents(6)。我记得我们曾在房间里花了好几个小时,试图弄清楚如何命名这些我们现在叫做*Intents*的东西。我们花了好几个小时讨论‘车棚涂漆’(7),试图找出最合适的词。最终我们想出了‘Intent’。”^(8)
“我们都为它背后的总体理念感到兴奋:我们如何让一个应用能够调用另一个应用,而不需要知道那个应用是否已安装?我们会说,‘有人能处理这个吗?’如果能处理,就行。我们都很兴奋。”
所有这些工作都发生在平台不断发展的同时,团队也在不断壮大。“我还参与了人员的招聘。我们需要 Java 工程师。我们现在就需要一百个 Java 工程师。所以当时的招聘、面试非常疯狂,同时也写了大量的代码。然后又扔掉了很多代码,因为我写的很多代码是调用的 API,这些 API 一周后就被修改、移除或者更改了。”
应用开发人员在基于一个正在并行开发的平台编写代码时,必须执行一场复杂的舞蹈。该平台的许多功能和 API 处于变化之中,而应用所需的许多功能根本不存在。^(9) 必须有人实现这些功能,才能让应用做它们需要做的事情。在 Android 上,这通过小团队在平台和应用程序的各个部分进行大量工作来实现。罗曼·盖伊说:“团队很小。进行这些更改的速度相当快;我们所有人都能访问整个源代码树。我记得在 1.0 发布之前,我对视图系统做了很大的改动,以清理 API。你做一个 CL,涉及 800 个文件,并在修改时修复所有应用。所以这不完全是应用需要这样做,尽管也是这样。每个人都在出力。”
Gmail 需要处理的一个硬性约束是性能问题。最初,Gmail 应用是以每条消息都有自己的 WebView 来编写的。^(10) 实际上,每条消息都是一个单独的网页,这会带来许多开销,而这些开销在用户看到的屏幕文本中并不明显。罗曼说:“但这对设备来说太吃力了。所以迈克重写了这一切。”
当时 Android 工程团队的负责人 Steve Horowitz 谈到了 Gmail 的性能问题。“Cédric 在架构上采取的方法在某些时候是有效的。老实说,部分原因可能仅仅是当时视图系统的能力限制。你能堆叠多少个视图来创建那些线程?”
“所以迈克不得不来解开这些问题,并重新做一遍,这样整个线程就不再是一个独立的视图,而是渲染到一个视图中。为了让它能正常工作,Gmail 的架构进行了根本性的重构。”
与此同时,使用 WebView 的要求给团队带来了额外的压力。使用 WebView 是有道理的,因为电子邮件消息需要网页功能。尽管许多电子邮件消息显示的是纯文本,但这些文本可能包含各种变化,并且格式也各不相同,因此能够显示该消息的 HTML(网页)版本是必要的。
因此,团队依赖于由浏览器团队开发的 WebView 组件。但 Gmail 消息中嵌入的 HTML 并不是普通的 HTML。它是一个内容类型的子集,并且对如何显示这些内容有一定的期望。要使其在 Android 上正常运行,就需要理解 Gmail 在后端的处理方式,并让浏览器(和 WebView)团队能够显示这种 HTML 的奇异变体。
在为 Gmail 开发时也有很多值得开心的事。那时开发安卓应用程序的一个重要动力是,这个平台拥有其他地方没有的功能。工程师们能够创造出比以前更强大的应用体验。
“我知道我们做对了什么,是第一次能够收到推送通知时的感觉。我们不确定是否能做到,是否能保持连接并让服务器告诉我们,‘你有新的邮件。’对于 J2ME,我们没有这个功能;你需要不断地刷新。但在某个时刻,我能够发送一封邮件,看到我的手机有反应。我做的第一件事就是跑去斯蒂夫·霍洛维茨的办公室展示给他看。他的下巴都掉下来了。他知道我们在做这个,但他不知道我们是否能做到。”
罗曼·盖伊说,“我喜欢第一款安卓手机,1.0 版,最喜欢的一点是我们有了邮件和聊天的推送通知,这在当时非常重要,因为 iPhone 没有这个功能。我记得我的手机比我的桌面电脑更快收到邮件。我的手机会发出提示音,几秒钟或几分钟后,我的桌面才会显示新邮件。”
尽管塞德里克负责 Gmail 的安卓端,但整个应用程序的大部分功能依赖于与 Gmail 后台通信的机制。这项工作是在安卓服务团队中完成的。
第二十章:Android 服务
只需轻轻点击鼠标,就可能导致移动行业前所未有的灾难^(1)。
— Android 服务团队口号
在大多数情况下,Android 团队与 Google 其他团队独立运作。Google 为项目提供资金,并与领导团队保持联系,但其他方面则让他们自行决定。Android 团队低调工作,编写操作系统、工具、应用程序及其他所需的所有内容,而无需与 Google 更大的工程团队互动。
除了服务团队。
如果你正在开发一款单机游戏,只需处理本地设备和存储,你可以独立完成,不需要任何后端基础设施或机制。但对于大多数其他应用程序,它们需要处理应用外的信息,或是你希望存储在设备外的数据,你可能需要与后端系统进行交互。运行在设备上的应用程序,实际上只是通向存储在外部服务器上的数据和服务的窗口。地图、搜索、Gmail、日历、联系人、Talk、YouTube:所有这些应用程序都依赖于存储在 Google 服务器上的数据和功能。
Google 希望通过 Android 操作系统使其应用和服务能够在移动设备上使用。因此,解决如何将 Android 设备连接到 Google 后端服务的问题变得至关重要。
为了确保这项工作得以完成,Android 成立了服务团队,最初只有三个人:Fred Quintana、Malcolm Handley 和 Debajit Ghosh。
Debajit Ghosh 和日历
Debajit 一直以为他会在大学学习科学,同时通过编程来支持他的主要学术兴趣。但在高中时,他意识到他可以将编程作为自己的主要兴趣。因此,他改变了方向,进入计算机科学专业,1998 年获得硕士学位。
Debajit 花了几年时间从事语音识别工作,这项工作结合了他对移动设备日益增长的兴趣以及让用户能够随时随地获取信息的能力。2005 年,一位同事加入了 Google,组建了语音识别团队。他联系了 Debajit,看看他是否有兴趣加入 Google,参与移动技术的工作。
起初,Debajit 并不感兴趣,他想:“Google?我不想去 Google 工作——那家公司太大了。”但当他想到一些移动技术的可能性时,他改变了主意,想:“我不确定 Google 适不适合我,但了解移动技术真的很有趣。”
Debajit 于 2005 年初加入了 Google 的小型移动团队(不是 Android 团队)。该团队的任务是将公司服务提供给现有的移动设备,并邀请 Debajit 领导服务器端团队。“我开始做的第一个项目是将传统网页转码为可以在当时手机上极为简陋的浏览器上查看的格式。”手机上的浏览器应用会发出请求,试图查看某个网站。该网站的内容会下载到 Google 服务器,并转换为该有限设备可以处理的格式,然后这种简化版的网页会被发送到手机上。这与 Danger 多年前为 Hiptop 手机浏览器使用的方法相似,也与 WebTV 早期为其电视浏览器采用的方法类似,服务器负责转换网页的实际显示效果与设备实际能显示的内容之间的差异。
2005 年春天,Debajit 度假归来时,发现桌上堆满了简历,并收到了一项任务,要面试一个名为“Android”的初创公司,Google 有意收购这个公司。“我还处于度假后的迷茫状态,试图搞清楚,‘Android?这到底是个什么东西?’”
他对团队中的工程师进行了面试,包括 Brian Swetland 和 Ficus Kirkpatrick。“Ficus 花了很多时间谈论 Brian,所以我很早就了解了一些团队成员的个性。”
Debajit 继续在移动团队工作,偶尔与 Andy Rubin 和他的团队进行沟通。然后,在 2006 年底,他联系了 Cédric Beust,他曾是移动团队的同事。他还与 Android 的工程总监 Steve Horowitz 进行了交流,进一步了解他们的需求。团队开始考虑 Google 服务的内容。例如,Android 需要为日历应用程序制定一个方案,并考虑如何与 Google 的日历服务进行同步。
与此同时,Debajit 一直在做一个副项目,将日历信息同步到 J2ME 设备。他仍然对如何将信息传递给随时在外的人感兴趣,而日历数据是解决这一问题的重要组成部分。在与 Android 团队交谈时,他意识到,通过加入他们,他可以将副项目转变为全职工作。因此,他转到了 Android 团队,加入了现在由三人组成的 Google 服务开发团队。
团队中的每位工程师都负责为特定应用开发服务。Fred Quintana 与 Jeff Hamilton 合作,后者负责为 Android 编写联系人应用。Malcolm Handley 与 Cédric 一起开发 Gmail。Debajit 与 Jack Veenstra 一起负责日历应用程序。^(2) 所有这些应用程序都有相同的需求,即在 Google 服务器之间发送和接收数据,因此团队在一个集中式同步机制上进行了合作。
在初期的服务工程团队开始运作后,Andy Rubin 从他在 Danger 时认识的人那里引入了一位领导者来带领这个项目:Michael Morrissey。
Michael Morrissey 与服务团队
Michael Morrissey 在大学和研究生院学的是数学,但他意识到自己更喜欢做编程。^(3)他开始玩 BeBox,最终得到了 Be 的工作。
Michael 最感兴趣的事情之一是打印——他喜欢操作系统、驱动程序和图形代码之间的互动。这对他来说是件好事,因为当时 BeOS 的打印状态非常糟糕。Michael 记得,“Jean-Louis Gassée,Be 的创始人兼首席执行官,有一天因为无法打印而非常生气。他总是必须切换到 Mac 上打印东西。他真的,非常生气。”
Michael 鼓励外部开发者为 Be 编写打印机驱动程序。这也是他第一次遇到 Mathias Agopian(后来加入了 Android 的图形团队)。 “他编写了所有这些了不起的 Epson 驱动程序。他非常热衷于色彩方面的工作。他一直在不断发送这些驱动程序。”Mathias 做这些工作是作为兴趣爱好,但最终他加入了 Be。
Michael 在 Be 经历了一个毫无灵感的首次公开募股(IPO)后,离开了公司,并且公司接着转向了一个注定失败的互联网设备。根据 Hiroshi Lockheimer 的建议,他最终于 2000 年 3 月加入了 Danger。最初,公司在开发一款小型设备,可以携带联系人和电子邮件,然后通过连接其他设备进行同步。但是在 Michael 加入后不久,互联网泡沫破裂,迫使公司开始考虑其他产品方向,最终推出了 Danger 的 Hiptop 手机。
在 Danger 工作的期间,Michael 负责后端服务,将手机上的应用程序与 Danger 服务器上的数据以及互联网进行连接。“我喜欢服务器端的工作,于是我开始构建后端和设备与服务器之间的协议。”例如,Danger 手机用户需要连接许多不同种类的电子邮件服务。Danger 服务器不会将这些服务都本地化到设备上,而是通过服务器连接这些不同的电子邮件服务,并将结果翻译成 Danger 设备能够理解的单一协议。同样,浏览器也是通过服务器将完整的网页翻译成简化版,并发送到手机上。
Danger 的创新之一是设备与服务器之间的持久连接。通过这种连接,设备可以立即收到新的电子邮件或消息。这在 2002 年是一个巨大的突破。即使你当时拥有少数几款具备电子邮件功能的手机,这些设备通常也需要手动与计算机同步。所以,你会在会议结束一小时后才收到关于你需要参加的会议的消息。但在 Danger 手机上,你会在会议进行时就知道自己错过了会议。
2005 年,Michael 离开 Danger 加入微软,受到一个新兴项目的吸引,该项目旨在制造微软手机。当时,微软将操作系统授权给像 HTC 这样的制造商。但微软内部有人设想了一个未来,认为公司也可以制造自己的手机。这基本上就是苹果所追求的模式,只不过微软当时的操作系统是可以授权的(类似于 Android,不过 Android 是免费的)。
但该项目在公司内部难以获得支持,因为它与微软传统的软件业务背道而驰。在一次令人沮丧的会议中,Michael 回忆说,一位高管因为手机无法运行 PowerPoint 而拒绝签署该手机为 Windows 设备,尽管这个应用场景并不是手机的重点,而且这个功能非常有限的设备根本无法承担额外的负担。通过类似的会议和其他各种障碍,该项目在推进过程中遇到了很大困难。
与此同时,Andy Rubin 每个季度都会与 Michael 联系,看看他是否想来帮助 Android。最终,Michael 对微软的项目失去了耐心,于 2007 年春季加入了 Android,领导服务团队。他看了看团队的现状,告诉 Andy 和 Steve 他们需要做什么。“他们说,‘太棒了!去吧。去做。’”
Michael 帮助组织团队,确保所有事情都能顺利进行。“我在 Danger 工作时有幸接触过这些事情,所以我知道什么样的模式适用于这些事情。我看到了更大的图景,理解服务架构的必要性:如何建立持久连接,传输层应该是什么样的,以及你需要注意的所有‘地雷’。”
Michael 也在努力扩大团队规模。他需要那些懂得如何处理 Google 基础设施的人。“我很早就意识到,如果我们没有来自 Google 内部的人,我们就不会有任何进展,因为 Google 做事情的方式非常独特。如果我们引入那些拥有移动行业领域知识的人,但没有 Google 知识的人,那就不好,因为他们需要花费很长时间才能适应 Google 的工作流程。我觉得,如果我们从 Google 内部找人,然后把他们转到 Android,并且在此过程中向他们传授移动领域的知识,会更有效率。”
其中一个早期需要解决的问题是推送功能:当服务器端发生变化时(例如,用户的邮箱收到新邮件,或者日历事件更新),服务器需要更新设备,以确保手机上的数据与服务器上的数据匹配。Debajit 创造了“tickle”这个术语。“我们想要‘tickle’设备。我们提出了像 Light Tickle 这样的术语,告诉设备发生了变化,请进行同步。Heavy tickle:包括负载。我们更倾向于使用 Light Tickle 方法,但这取决于具体的使用场景。”
团队提出了一种方法,手机将与 Google 服务器后端建立一个单一的、专用的连接。这个连接被称为移动连接服务器(MCS),将是持久的,以确保信息可以随时发送或接收,保证手机在服务器上有新信息时能得到通知。每个应用都有其特定的数据需求,但它们都共享这个单一的连接,通过这个连接,服务器会提醒设备某些信息已发生变化。该连接还用于最初的 Google Talk 功能,用于发送和接收消息。
建立与 Google 服务器的持久连接不仅是一个技术问题,还涉及到资源有限的问题。

Michael Morrissey,2008 年 10 月 21 日——G1 发布前一天(图片由 Brian Swetland 提供)
网络运维团队控制着 Android 所需的持久连接机制。当时,Google 假设所有需要网络连接的东西都是基于 Web 的;数据传输请求使用标准的 Web HTTP 请求机制。但 Android 需要使用完全不同的协议,因此他们需要一个专用的网络资源,叫做虚拟 IP(VIP)。问题是,网络团队不愿意给他们提供一个。“Google 的构建方式,出于一些无聊的原因我不想细说,这些 VIP 非常稀缺。实际上,只能容纳大约 200 个。已经有一些被占用了,网络团队根本不愿意发放。”
Debajit 和 Michael 经常与网络团队会面,劝说他们为 Android 提供 VIP。这类讨论对 Michael 来说并不陌生:“我的很多工作都是四处奔走,试图说服 Gmail、日历、联系人以及所有其他团队,这对 Google 来说是一个重要的事情,他们应该在工程和 SRE^(4)支持方面帮助我们。”
最终,网络运维团队让步,临时为他们提供了所需的 VIP,并附带了一场友好的赌注。他们说,如果 Android 在前六个月内没有达到一百万用户,他们将收回 VIP,而 Michael 和 Debajit 则需要给他们送上一箱威士忌。Debajit 记得:“威士忌绝对是讨论的一部分,那就是我们的货币。”
他们成功建立了持久连接,并让 MCS 在 5228 端口号上运行。^(5)
Android 赢得了赌注,尽管 Michael 表示,这取决于你如何定义时间框架。网络运维团队说,从他们给了 VIP 的那一刻起算,而 Michael 则从 1.0 版本发布的那一刻起算。无论如何,当时显然 Android 已经足够成功,不会失去与这些 Android 设备的连接。
启动消防演习
Android 对持久连接的独特需求意味着它需要在特定数据中心配置专用的服务器。任何涉及数据的工作都知道,必须准备备份以防主系统出现故障。这就是为什么我们有冗余磁盘阵列和备份存储的原因,也正因为如此,许多家庭会有两个父母,以便孩子可以在第一次得不到答案时去问另一个父母。
但 Android 不仅仅是为了服务单个用户,或少数几个用户;他们需要一个能够扩展到更多用户的系统。一个备份站点是不够的。一个系统完全可能会宕机。而且,虽然不太可能,但第二个系统也可能会出现问题。因此,他们启用了第三个数据中心以防万一;三个肯定足够应对所有这些情况。
发布日:2008 年 10 月 22 日。Android 的一个服务器在那周早些时候已经宕机,但幸运的是在发布前恢复了。发布当天,第二个服务器由于“计划外维护”宕机。谷歌想要进行维护,所以直接将其从系统中移除。因此,在发布当天,Android 只剩下了两台服务器。幸运的是,两个服务器仍然足够支撑一个强大且具有故障容错的系统。
然后其中一台服务器着火了。
那天数据中心出现了过热问题,因此他们不得不关闭系统进行处理。迈克尔说:“我们真的是汗流浃背——我们只剩下一个数据中心!我们失去了两个;如果第三个也挂了,所有同步功能就无法正常工作——就不能有聊天什么的了。我们真的慌了。”
最后那个服务器保持运行,所以没有发生停机。但团队实际上距离失败比他们预想的要近得多。
Dan Egnor 和 OTA
如果不小心,你的 OTA 下载可能会导致世界“死机”^(6)。
——迈克尔·莫里西(由丹·埃格诺回忆)
从一开始,Android 操作系统的一个令人印象深刻的特点就是其无线(OTA)更新系统。偶尔(或者,如果你在运行内部的预发布版本,频率会更高),你的手机会收到系统需要更新的通知。最终你会厌倦它不断的提醒,决定让它继续更新,然后它就开始了。它下载更新,重启,进行配置,并显示登录界面;一切准备就绪。
作为用户,这可能不太明显,但你已经让手机在运行过程中完全替换了它的核心部分,而且一切都顺利运行。这就像是你在咖啡店排队时,大脑被替换了,然后继续点咖啡,仿佛什么都没发生过。
而且一切都正常运作。每次都是如此。嗯,好吧,有那么一次……稍后再讲。
在早期,团队就认识到远程更新手机的重要性。更新可能是针对平台下一个版本的重大更新(例如从 Android 8.1 Oreo 升级到 Android 9 Pie),也可能是较小的更新,比如每月的安全补丁或漏洞修复更新。或者,如果发布出现严重问题,可能还需要紧急修复。无论如何,必须有一种机制,让设备能够接收这些更新,而无需通过合作伙伴、运营商或其他可能阻碍 Android 更新传播的渠道。
2007 年 8 月,Michael Morrissey 把 Dan Egnor 带进来,负责更新系统的工作。
Dan 从小就开始编程,常常待在母亲所在大学的计算机实验室里。最终,学校加强了管理,不允许教职工的子女进入实验室,这时他的母亲给他买了一台 Atari 400。“我用得非常频繁。所有的大人都对我在这个滑稽的薄膜键盘上打字的速度感到印象深刻。”
大学毕业后,他先是在微软工作,然后去了一个初创公司,接着成为了华尔街的一名量化分析师^(7)。2002 年,谷歌举办了一场编程竞赛,Dan 出于兴趣参加了,并获得了胜利。“他们提供了一些文档,并让我们做些有趣的事情。我做了一个小型的地理搜索应用。他们把我飞到山景城,让我和一群人谈话,并问我是否有兴趣加入他们的团队。”
Dan 拒绝了他们的邀请。他希望留在纽约,而谷歌那时在纽约没有办公室。他的拒绝让谷歌团队感到困惑,因为那场竞赛本来是作为招聘手段的。一年后,谷歌在纽约开设了办公室,Dan 作为第二名员工加入了公司。他开始从事搜索和地图相关的项目,最终搬到了山景城。
与此同时,Dan 和谷歌的其他人一起听到了一些关于 Andy Rubin 的那个秘密项目的传闻。“一切都非常保密。‘他们在做相机吗?Andy Rubin——他不是 Danger 的那个人吗?’”
Dan 一直是移动设备的爱好者。“我从 Hiptops 问世起就一直在使用[Danger] Hiptop,还是它的忠实粉丝。而且,我也是移动计算的粉丝。那时我就是那个带着奇怪的小型迷你 PC 和无线电系统的人,能够随时随地上网,当时做到这一点可是非常疯狂的。我是早期 Wi-Fi 和相关技术的爱好者,那时候 Wi-Fi 还非常新鲜,甚至有用户组可以参加,你可以和其他 Wi-Fi 爱好者交流,这将改变一切。”所以他对 Android 小组的动向很感兴趣。
与此同时,Michael Morrissey 正在寻找像 Dan 这样的工程师加入服务团队;他需要熟悉 Google 后端的工程师,因为 Android 设备需要与这些服务器进行通信,所以需要专家来创建相关的软件。时机恰到好处,Dan 在 2007 年 8 月加入了团队,距离 SDK 发布还有三个月,距离 1.0 版本的发布还有一年。
Dan 加入了那个小型服务团队,团队成员当时包括经理 Michael Morrissey,以及工程师 Debajit Ghosh、Malcolm Handley 和 Fred Quintana。其他三位工程师专注于数据同步以及他们所使用应用的具体细节(分别是 Calendar、Gmail 和 Contacts)。Dan 在这些方面提供了一些帮助,同时也负责整体服务的核心基础设施,但他主要负责他们所称之为设备管理的工作。这项工作包括空中下载(Over the Air, OTA)更新以及签到服务。虽然当时已经有一个基本的更新机制,但 Dan 重写了它,最终形成了 Android 启动时使用的系统。
Dan 得到了经理的帮助和建议。“Michael Morrissey 就是那种经验丰富的老手——我的意思是,他并不比我年长——但他有着智慧的声音。他在 Danger 管理过类似的事情,见识过很多复杂的情况,确实有着非常智慧的经验,知道该关注什么、该集中精力做什么、哪些架构可能有效、哪些可能会成为痛点。他记得很多时候,能够迅速推送 OTA 更新来解决问题,拯救了公司。所以这非常重要:如果你的设备出现了问题,能够快速发布一个修复补丁。或者如果遇到安全问题,快速的 OTA 解决方案也至关重要。如果可以避免,我们绝对不希望把这个交给运营商。”
同时,OTA 系统本身必须经过精心设计,以预见所有可能出错的情况,从设备存储空间不足、更新过程中重启到安全漏洞。团队对这些问题进行了深思熟虑,提出了一个架构,到目前为止似乎运行得相当顺利。
首先,团队将设备上的数据分为系统和数据两个部分。系统分区包含了 Android 平台本身以及预装应用程序,并且是只读的(除了 OTA 更新)。设备上的其余信息,包括下载的应用程序、应用程序数据、用户偏好设置和账户信息,都存储在数据分区中。这种分区方式意味着,如果发生严重故障,设备可以进行恢复出厂设置,清除整个数据分区,至少手机还能继续使用。用户需要重新设置账户并重新安装应用程序,可能会丢失一些应用程序特定的数据^(8)。但大部分数据依然是安全的,因为它们要么存储在外部 SD 卡上,要么保存在云端。
在更新过程中,只读的系统分区必须被修改,因为更新的内容必须写入该分区。问题是:更新系统如何确保有足够的空间,正确的部分被修改,并且即使在极端情况下,如手机在更新过程中重启或电池耗尽,更新仍能顺利进行?
解决方案是采用一系列增量更新。因此,更新不再将整个 Android 系统视为一个单一的、没有形状的整体,而是将系统划分为独立的部分,逐一处理。例如,一个更新可能包含框架、媒体堆栈和短信驱动程序的新部分。这些部分可能会被存储在不同的模块中,可以独立处理。更新系统将这些模块的更新打包,在开始更新过程之前下载所有模块的更新。更新会重启并启动更新应用程序,逐一处理每个模块,安装每个模块,验证结果是否如预期,并将新模块替换旧模块,然后继续处理下一个模块。如果手机在更新过程中死机或重启,更新会从中断处继续,而不会留下一个未完成、不确定的状态。“我们的目标是,即使屏幕上显示‘请勿关闭手机’,如果发生多次重启、电池拔出等情况,最终仍能完成更新。”
其中一个可能出现的问题是存储空间不足。如果设备上没有足够的空闲内存来下载更新怎么办?或者,如果更新导致系统文件过大,超过了可用内存,并在更新过程中空间用尽怎么办?这在早期的 Android 设备上尤为令人担忧,因为那时空间非常紧张,用户很可能已经使用了大部分可用存储空间。
幸运的是,团队预见到了这个问题。确保更新有足够空间的主要策略是使用缓存。“我们有一个专门为此目的设置的缓存分区。它是共享的。应用程序可以把临时数据放在里面,这些数据是允许被删除的。但它的主要存在是为了让 OTA 系统能够下载到其中。”虽然缓存名义上是供应用程序使用临时文件,但它的真正目的是让更新系统能够正常运行,以便始终有足够的空间供更新下载和安装。
当然,理论上系统可能还是会用完空间。毕竟,Android 是为各类制造商和各种不可预测的配置而创建的。在这种情况下,可能就无法进行 OTA 更新;但它仍然不会让手机变成无法使用的状态。“有时候设备满了,缓存满了,又没人删除这些数据,那么 OTA 下载可能会失败。所以你可能得不到 OTA 更新,如果它是至关重要的,那就糟糕了。但这总比更新后让你把手机变成砖头要好。”
更新的最终领域要解决的是安全问题。更新被允许写入本应只读的分区,以便它们可以更新设备上的核心操作系统。那么,是什么阻止了恶意软件伪装成更新并同样更改系统软件呢?
Dan 和团队在 Android 安全团队的帮助下,采用的方法是只允许受信任的文件替换系统中的文件。更新模块每个都用密钥签名,系统可以验证这些密钥是否被 Android 信任。安全团队增加了另一个保护层,使得每个完整的更新除了每个单独模块使用的密钥外,还增加了一层密钥加密。通过所有这些层次,系统被认为是安全的,可以进行发布(并且可以更新)。
发布后,Dan 在网上搜索,看看是否有人在探讨更新的安全性,以确保没有问题。他在一个黑客论坛上发现了相关讨论。“人们对黑进这部手机很感兴趣。有一个在论坛上相当受人尊敬的人说,‘放弃吧。代码很稳。我能读懂它的工作原理。你不会突破的。游戏结束——去别的地方找吧。’”
Dan 在当年的年度绩效评审中引用了这个讨论,当时他在谈论自己在 OTA 系统方面的工作时总结道:“互联网已经审查过我的代码。”
Android OTA 的一个令人印象深刻的地方是它们自始至今的可靠性。团队的工程师们已经进行了数百次更新,既包括内部的预发布版本,也包括官方版本,而且没有出现问题。
但是有一次……
最初,更新机制提供了一个整个系统的单一、大型二进制文件。因此,即使只是对平台的某个特定区域做了小的更新,更新也需要下载并安装整个系统。这对用户或运营商来说并不是一个良好的体验,因为这样大规模的更新需要大量的存储、带宽和时间。
在 1.0 版本发布后不久,OTA 团队(现在包括道格·宗克尔和丹·埃格诺)实施了差异更新。系统会识别出之前的系统和新系统之间发生了什么变化,只下载和安装那些发生变化的部分。系统正常运行,团队准备将其发布到实际使用中。
当时,迈克尔正从西雅图搬到山景城。他想着:“一切看起来还不错,我打算休息一周,搬家给家人安排一下。几天后,周二晚上十点,我的手机响了。是丹·埃格诺打来的。我接起电话,问‘丹,怎么了?’他说,‘首先,我想让你知道,一切都很好。’那一瞬间我就知道——这根本不好。‘但是……我们把一堆设备弄成了砖头。’”
问题出在用来创建此次更新的差异镜像与 HTC(G1 的制造商)放入手机中的镜像稍有不同。使用差异更新的机制只有在系统完全匹配时才会正常工作。所以当该更新应用到这些手机时,系统被破坏,设备被变砖。
好消息是,只有 129 个设备受到了问题的影响。对于这些用户来说,情况仍然很糟糕,需要大量客户服务工作来更换这些手机。但考虑到所有 G1 设备的数量,129 个受影响的设备对于这种灾难性故障来说已经算是不错了。问题之所以得以有效控制,是因为团队使用的分阶段推出和检查服务机制按预期工作;丹和道格在更新发布过程中一直在监控进展。他们立刻发现了问题,并停止了更新,直到诊断并修复了问题。
这次故障还导致了新政策和新流程的出台,以确保类似问题不再发生。到目前为止,它确实没有再发生。
当团队开发 OTA 系统时,更新并不是移动设备的常见功能(当然,Danger 设备除外)。iPhone 首次发布时也没有这种更新功能。要更新 iPhone,你需要将它连接到你的 Mac,和同步 iPod 上的音乐一样。如今,空中下载更新已成为我们无线移动现实的一部分。你的手机会无线下载并重新配置整个操作系统,然后重新启动到新的操作系统中,当然,一切都会好起来的。有什么可能会出问题呢?
使 OTA 更新能够可靠工作的另一个必要部分是签到服务,它为 Android 服务器提供了监控现场设备的能力。Dan 写下了该系统的基础部分,但在 2008 年初,当 Chiu-Ki Chan 加入团队时,他获得了一些帮助。
Chiu-Ki Chan 与签到服务
Chiu-Ki 在 8 岁时开始了软件开发的旅程,那时她母亲让她参加了一个暑期编程课程。他们原本以为她只是学会一些计算机使用技能,但课程内容也涉及了 BASIC 编程,而 Chiu-Ki 很享受,特别是她从中获得的那种掌控感。“作为一个 8 岁的孩子,我真的很喜欢指挥计算机。在现实生活中,人们指挥我,但作为孩子,你可以告诉计算机做点什么。”
多年后,在获得计算机科学硕士学位后,她于 2003 年加入谷歌,从事搜索质量工作。这个项目很合适,因为她在研究生阶段专攻文本处理。
在从事搜索工作几年后,她希望尝试一些新的事情。她在 Android 团队有朋友,包括她在搜索团队认识的 Dan Egnor,因此她在 2008 年 2 月加入了服务团队。Android 团队在前一年的秋天发布了公共 SDK,但距离 1.0 版本发布还有几个月。
和 Dan 一样,Chiu-Ki 有着 Google 后台基础设施的经验,因此服务团队成了她开始 Android 之旅的理想地方。最终,她会在 Android 市场团队和地图团队工作。但刚加入时,她帮助处理签到服务,为 1.0 版本的发布做准备。
签到服务与 OTA(空中下载)紧密配合,随着更新推出到设备群体中。根据他在 Danger 的经验,Michael 相信应该慢慢推出更新,采取可追踪和回滚的方式。Dan 记得 Michael 曾告诉他,“‘如果你不小心,你的 OTA 下载可能会把整个世界搞崩溃。’他坚持非常正确地认为,应该采取分阶段推出的‘金丝雀’过程,我们首先向内部用户推出更新。我们将有办法监控他们是否能够启动并运行新操作系统,并且是否仍然在进行签到。我们会有这些图表[签到结果的实时图表],以便我们能交付给内部用户,观察他们重新启动时的变化。然后我们会将其发布给 0.01%的外部用户,观察相同的图表,看看是否有异常。接着我们会从 0.01%到 0.1%到 1%到 10%的逐步推送,始终观察这些图表,寻找信号。”
杰出服务
服务团队为 Android 提供的基础功能不可小觑;它们是让 Android 平台对用户如此强大的基础。像内核和框架这样的平台组件仅仅是为了让设备能够启动和运行。但如果没有那些让用户能够即时接收消息和电子邮件、同步日历或联系人信息,或者获取必要的版本更新的服务,Android 就不可能像现在这样成为一个有吸引力的智能手机平台。
第二十一章:21
位置,位置,位置

查尔斯·门迪斯和 Bounce
最具吸引力的移动应用之一是地图。能够看到你的位置并导航到你想去的地方,几乎是所有手机的杀手级应用。但在很久以前,在 Android 1.0 之前,这个应用并不存在。Android 必须组建一个团队来实现这一目标。
与此同时,谷歌的另一位工程师查尔斯·门迪斯有了一个需要地图技术的不同应用的想法。
查尔斯·门迪斯曾在澳大利亚的银行业工作,但他的一位朋友鼓励他申请加入谷歌。那位朋友最终去了亚马逊,而查尔斯在 2006 年加入了谷歌。“我加入谷歌是想借此机会看看美国。我以前从未去过。我的妻子和我结婚了,我们想旅行,看看这个世界。这看起来是一个很好的方式,让我可以住在美国,看看这个国家。计划是四年后回到悉尼,开始组建家庭。”那已经是很多年前的事了,查尔斯现在依然住在加利福尼亚,依然在谷歌工作。
查尔斯最初加入了广告团队。“当你刚开始的时候,你有两个选择:选择搜索还是广告。^(1)你是想做搜索方面的工作,还是想赚钱?我被分配到了 AdSense。”
当时查尔斯对移动技术并不感兴趣。“我那时没有手机。我从不喜欢手机;它们很麻烦。人们可以随时打扰你。谁想要那种生活?”
但第二年,查尔斯的妻子怀上了他们的第一个孩子,这让查尔斯产生了一个应用的想法。“我想知道她在哪里。如果我需要去接她带她去医院,我希望能够看到她的位置。”他想开发一个可以提供这些信息的应用。
2007 年春天,他设法从 Android 团队那里得到了些硬件。“我一直催 Ryan Gibson 和 Brian Jones,他们给了我几台 Android 设备。”
“我想熟悉安卓开发,所以我说服了我所在的团队,AdSense 前端团队,加入开发者计划。Ryan 面临一个挑战,他们希望人们开发应用,获胜者将获得更多的 Sooner 设备。我想要多几个设备,^(2)因为我希望我的妻子有一个,我也要一个。所以我们开发了一个叫 Spades 的游戏。^(3)这是一个网络多人游戏,四个人可以加入并玩一局 Spades。我以前每周五都和同一群人一起在家里玩。”
团队在几个月内开发了 Spades 应用。
“我们开发完这个应用后,再也没有玩过这个游戏。我一直在催他们测试这个应用,他们就像‘我讨厌这个游戏,我再也不想玩了。无论何种形式,我都不想再玩这个游戏了’。”
“但幸运的是,我们得了第三名,并且作为参与的一部分得到了很多设备。”
这是 2007 年 8 月初。查尔斯拥有了他团队所需的设备,并且他也有编写 Android 应用的经验。现在他可以编写他最初设想的定位应用,用来追踪朋友们的位置。他把它叫做 Bounce。
“我们想象着人们在四处‘弹跳’。随时,我都能看到你的位置。问题是,我怎么获得位置呢?那时 [在 Sooner 设备上],我们没有 GPS。所以我从亚马逊上买了这些蓝牙 GPS 设备。蓝牙在 Android 上并不好用。它是有的,但没有 API。”也就是说,系统具备蓝牙功能,但没有办法通过应用访问这一功能,因此 Bounce 无法使用蓝牙与 GPS 设备进行通信。
然而,一个应用程序可以像在 Windows 的 DOS shell 或 Mac 的 Terminal 控制台中输入命令一样,向系统发出命令。
“有一个非常长且复杂的命令,它实际上是为了设置蓝牙连接到你的 GPS 设备,所有这些都绕过了我们没有 GPS 的事实。然后我就可以读取通过蓝牙输出的 GPS 数据流。”
所以现在查尔斯通过蓝牙从 GPS 设备获取了位置数据。但该如何处理这些数据流呢?他不想写一个服务器来记录位置;他只想用它来和朋友之间实时地发送位置。
“我们开始使用 SMS 作为我们的传输协议和服务器。你会有一个 GPS 设备,我也有一个。当我打开应用时,我可以说‘请求 [朋友的] 位置。’它会发送一条 SMS 到你的设备,Bounce 应用会拦截这条 SMS 并询问,‘查尔斯是我的朋友吗?如果是的话,让我把我的 GPS 位置发回去。’
“所以我们有了一个基本版本,在这个版本中,我妻子可以看到我的位置。”
在 9 月 15 日,将会有一次关于是否启动 Android SDK 的执行审查。埃里克·施密特、拉里·佩奇和谢尔盖·布林都会出席。安迪·鲁宾会进行展示,并且斯蒂夫·霍洛威茨也在场,他们请求查尔斯带上他的 Bounce 演示。
那天早上,演示仍然没有完成。查尔斯和团队为 Bounce 添加了一个功能,叫做 Memory Lane,它会显示你的位置信息历史。但这个功能是最近才上线的,自那时起,他只是去过工作和(偶尔)家里。他需要添加一些实际的位置信息来演示这个功能,所以他开车四处绕行,路上添加了一些数据点,最终进入办公室。
早上 9 点,他准备好出发了。“我只是确保蓝牙设备已经配对,然后走进会议室。埃里克坐在桌子的首位,拉里和谢尔盖坐在他们常坐的位置。乔纳森·罗森伯格也在场。会议室已经很拥挤了,整个团队都在场。我坐在后面,然后安迪·鲁宾开始了演讲,‘我们今天要讲讲 Android,最后我们会做一些演示。’
“埃里克说,‘我们跳过演示吧。’”
“他们转向我说:‘好了,查尔斯,轮到你了。’”
查尔斯向他们展示了 Bounce,接下来的时间里,他回答了他们关于当时为 Android 开发的经验问题。
最后,埃里克告诉安迪,他们获得了启动的批准。^(4) 两个月后,他们确实启动了。
“会议结束后,安迪转向 Steve,说‘那个人会加入我的团队,搞定它。’然后 Steve 告诉我,‘嘿,你要加入 Android 团队了!’”
“我当时想,‘其实,我挺喜欢做 AdSense 的工作。’” 查尔斯刚刚成为团队的技术负责人,一切都很不错。“但是 Steve 和我聊了聊,他相当擅长说服我。几周后,我加入了 Android 团队。”
原本计划在 11 月的发布会上展示 Bounce。到那时,Bounce 已经使用了与其他 Google 服务相同的 Google Talk 连接,这比以前用的 SMS 破解方法要好。但是当时 Google Talk 并不稳定,经常掉线,双方的应用无法做任何处理。最后,Steve 决定不在发布会上演示 Bounce,以避免在媒体面前出现失败的可能性。
最终,查尔斯需要将 Bounce 从一个演示版本转变为一个产品。他做的第一件事就是解决 Google Talk 的连接问题。查尔斯和魏黄一起合作,最终让其在 Bounce 以及其他 Google 服务应用中都能正常工作。
另一个需要改进的方面是定位服务。查尔斯在演示中使用的 GPS 设备仅仅是一个权宜之计,因为早期的 Sooner 设备没有内置 GPS。在那次 9 月的高层会议上,谢尔盖建议他通过蜂窝塔和 Wi-Fi 数据来获取位置。这种方法已经在进行中:查尔斯已经开始与同一楼栋中另一个团队合作,那个团队正在实现地图功能 我的位置(也叫做“蓝点”)。这种技术使用蜂窝塔和 Wi-Fi 路由器的数据来定位蓝点,周围圆圈的大小表示不确定性半径(因为蜂窝和 Wi-Fi 定位不如 GPS 精确)。
但查尔斯也需要为其他内建更多定位功能的设备做好计划。G1 设备实际上有 GPS 硬件,因此当 GPS 可用时,Bounce 可以直接使用这些数据。
查尔斯与迈克·洛克伍德合作,后者负责为 GPS 和其他硬件传感器编写支持代码。但查尔斯在使用设备上的 GPS 时遇到了一个问题:“它非常耗电,而且非常慢。”解决方案是,位置服务通常使用更轻量且更大致的蜂窝/Wi-Fi 数据,但当用户直接使用地图应用时,会启动 GPS 以获取更精确的位置数据。这种方法避免了 GPS 硬件持续运行导致的电量消耗,同时在用户明确需要时提供更精确的位置数据。
Bounce 最后需要的是一个名字。Bounce 只是一个代号,但产品在发布时需要一个真实的、可以注册商标且不侵权的名字,于是团队开始讨论一些创意。
“我们在谷歌有一个团队:他们专门负责命名。我们去找了他们,他们有一堆名字,其中很多已经被版权保护。我们说,‘不如选一个描述性的名字叫 Friend Finder。’然后有人提醒我们,那个名字已经被一个成人交友网站注册,叫做 Adult Friend Finder。所以我们完全不打算接近那个名字。”
团队在没有名字的情况下卡住了。然后,他们在发布前的几周与拉里·佩奇进行了交谈。“拉里说:‘Latitude 怎么样?你知道,代表自由、运动……而且它与位置相关。’于是,拉里想出了这个名字。”
显然,对于拉里来说,成为谷歌的创始人和高管还不足以占据他的全部工作时间;他还负责命名产品。
到这时,Latitude 已经作为地图的一个功能集成,而不是一个单独的应用。它没有出现在 1.0 版本中,因为初始发布需要优先完成其他工作。但它在几个月后,也就是 2009 年 2 月,首次上线,并同时支持安卓、黑莓、Windows、塞班系统和网页版。
地图
“应用有些争议,主要是因为所有权问题。”史蒂夫·霍洛威茨说。“比如:地图。地图是谷歌的明星移动应用。事实上,谷歌在移动端真正拥有的就是地图。所以我们想要开发地图,或者把地图从[移动团队]那边移过来,但移动团队并不完全相信[安卓]。最终我们说服他们派了一位工程师来帮忙将地图移植到安卓操作系统。他[亚当·布利斯]从地图团队过来,帮助使地图应用能够在安卓上运行。”
鲍勃·李和亚当共用一个办公室。“他在开发安卓上的第一版地图应用。我们有了一个 G1 屏幕的原型。他做了一个演示,这就是第一次完整的地图界面。你可以在大屏幕上四处拖动。安迪[鲁宾]因为这个原因把团队里的第一个 G1 原型机给了他。”
2007 年末,查尔斯加入了亚当的团队,他放下了自己的 Bounce 应用,专注于地图应用的发布。“我加入安卓是为了开发[Bounce],但很快它就被取消了,因为我们有更重要的事情要做。在我们推出位置追踪这个闪亮的新特性之前,我们需要先有地图应用。”
地图并不是 Charles 唯一的工作内容。像其他 Android 团队成员一样,他做了许多必要的工作。“我做了很多 Dialog API,工作于 ListView、TextView,以及系统服务器的一些基础工作。每当 Dianne 的工作过载时,我会修复她的一些小 bug,或者是 Jason Parks、Jeff Hamilton、Mike Cleron 的 bug。我最终成了一个消防员,无论哪里需要,我都会去。短信应用、彩信应用、Gmail 应用,我做了不少工作。但主要还是在与 Adam 一起开发地图应用。我还希望能够使用 MapView API 和 Location API,因为我们需要 Location API [用于 Bounce]。”
大约在他加入 Android 一年后(大约在 Android 1.0 发布时),Charles 转到了地图团队,并成为了团队负责人。“那时有一个地图团队,我曾和他们一起工作,主要是处理 My Location 的功能。我想说,‘嘿,我们应该将地图应用程序和那个团队合并,实际上扩展地图应用的功能。’因为如果你回顾一下那个时候,地图应用运行在 Windows Mobile、Symbian 和 BlackBerry 上。那时 BlackBerry 可以说是霸主,几乎占据了大部分市场份额。它的功能远比其他平台丰富,比如交通功能。因为他们在全球有大约 30 到 80 人在开发这个应用,而在 Android 上,只有我和 Adam 在做这项工作。但是我们都是基于相同的 API 开发,我们使用的是他们的服务器 API。所以最后,在经过多次讨论后,我从 Android 团队转到了地图团队[和 Adam Bliss 一起]。我依然待在 44 号楼,只是把我的办公桌搬到了几间隔间外。”
转到那个团队的一部分工作是成为移动地图的总体负责人(包括 Android 和其他平台)。但领导这个团队并不意味着可以随心所欲。“当时,我试图说服大家,‘我们应该停止在 Symbian、Windows Mobile 和 BlackBerry 上工作,转向 Android,因为我认为 Android 将是未来。’大家都说,‘你疯了吗!我们没有 Android 用户。看看每个月有多少 BlackBerry 出货!这比你一年出货的量还多。’”
“最后,我们决定从为 Android 构建的代码库转移到我们所称的‘统一代码库’。所以我们简化了,并没有使用所有的 Android API。你不能使用 HashMap,只能使用 Vector。你不能使用 LinkedList,只能使用 Vector。基本上,Vector 是你能使用的唯一数据结构。”
“我们转到了那个代码库,这给了我们很多 Android 上的功能,因此 Android 用户突然拥有了更多功能完整的地图应用。但我不能使用 Android 的所有功能。”
最终,在 2009 年底 Droid 发布后,Android 开始获得大量用户,地图团队的讨论发生了变化。“那时,我终于可以带着 Android 的增长回到团队,并开始将我们从 Symbian、Windows Mobile 和 BlackBerry 转向 Android。”
“我记得接管团队时的情景。两年后,我说服他们全力投入 Android 平台。在此之前,他们一直认为‘不,我们必须支持所有平台。’但是特别是在 Droid 发布后,我们的用户群开始急剧增长。我们开始能够进行 Wi-Fi 扫描、蜂窝扫描。当我刚开始的时候,我记得蓝色圆圈,表示不确定性的半径,一度达到 800 米。经过一两年,我们将蜂窝的误差缩小到了 300 米以内,而 Wi-Fi 的误差从大约 300 米降到 75 米。所以,单是 Android 收集到的数据^(5),就极大地帮助了让蓝点更精确。”
导航
“我加入地图团队的同时,”查尔斯说,“我也开始研究逐步导航功能。那时候,你要购买 Garmin 设备,并且需要付费。即使是在 iPhone 上,你也需要每月支付 30 美元。我们觉得我们可以做出这个令人惊艳的体验。”
但是首先必须解决另一个问题:地图应用程序使用的数据格式。当时应用中显示的地图基本上是静态图片,这在可用性和尺寸上都有问题。“我们使用的是栅格地图,也就是 PNG 格式的图像。^(6) 如果你旋转地图,文字会倒过来。如果你想倾斜地图,是做不到的。”此外,用于地图的图像非常大,需要大量带宽来下载。
当时在西雅图办公室的基思·伊藤,正致力于逐步导航功能。为了解决数据问题,他研究了一种新的地图显示方式,使用了矢量图。^(7) 矢量图是一种用几何学来描述图像(如地图)图形的方式,而不是使用图片。服务器传输的不是嵌入文本的地图图像,而是通过几何描述,设备在适当的分辨率和旋转角度下绘制地图。这种方式比 PNG 格式的地图所需的数据量要小得多。
基思制作了一个新型基于矢量的地图演示,并将其发送给查尔斯,查尔斯带到安迪的办公室:“拉里在办公室。我给他们看了矢量地图。你可以进行倾斜和缩放。以前我们只有离散的缩放级别,现在你可以稍微缩放或者大幅缩放,文字也不会扭曲。”
但是有一个权衡:性能。“在 G1 上做这件事是非常困难的,因为我们需要渲染它。”也就是说,逐个矢量地绘制地图几何图形,比直接显示图像要花费更多的时间和精力,但所需的数据量却减少了一千倍。
安迪知道即将推出的 Verizon 设备对他来说很重要。“在 Droid 上的逐步导航,成为了其标志性功能之一。”基思继续与查尔斯合作,既推进矢量地图的产品化,又推进逐步导航功能的开发。
在将这个功能推出 Droid 上时,仍然有一些障碍需要跨越。首先,Verizon 已经有一个现有的应用程序 VZ Navigator,他们对这个应用收费,并希望继续提供它。但这个功能最终还是成功地推出了 Droid^(8),并进入了市场。逐步导航不仅推动了导航和地图的使用,而且还促进了 Droid 的销量。人们意识到,他们可以利用自己的手机和现有的数据计划到达目的地。
第二十二章:Android Market

今天,我们理所当然地认为,已经有了一个我们可以去购买应用的地方。你有手机,想要一个应用——你就去应用商店下载,显然。
但在 Android 和 iPhone 出现之前,这种简单的生态系统并不存在。
并不是公司不想要这样的存在;他们一直在尝试创造类似的东西。你可以从运营商那里购买服务(主要是铃声和简单的工具),也有各种游戏库。但当时,应用市场并不存在(因为当时那些有限的设备上应用能做的事情不多),所以用户也没有错过什么。但一旦出现了足够强大的设备来运行真正的应用,用户就需要一种便捷的方式来获取它们。
但运营商已经创建了围墙花园^(1),他们控制着早期应用商店的访问权限。他们希望确保恶意或不良应用不会破坏他们的网络,因此不希望无法控制的随机应用在他们的网络上运行。他们创建了精选平台,比如 Danger 手机上的应用商店。但这种额外的流程和麻烦劝退了许多开发者上传应用,也阻碍了更大规模应用商店生态系统的形成。
Android 想要通过 Android Market 解决这个问题。他们希望创建一个任何人都可以上传应用的商店。负责 Android 服务团队的 Michael Morrissey 告诉 Nick Sears 他的目标:“我希望堪萨斯州的一个十四岁孩子,早上写完一个应用,下午就能上传到 Android Market,并且能够销售给所有的用户。”
这个概念涉及了 T-Mobile(Android 1.0 设备 G1 的首发合作伙伴)。他们如何验证堪萨斯州的那个孩子无法上传会导致网络崩溃的内容呢?
于是,Android 和 T-Mobile 开始了长时间的讨论,以解决如何确保这一切能够顺利进行的细节问题。Android 团队必须做两件事才能让 T-Mobile 同意。首先是确保 T-Mobile 的网络是安全的。其次是允许 T-Mobile 拥有自己的精选应用商店,并与 Android 的商店并存。
第一项,即安全性,从确保平台的安全开始。由于应用在内核级别的沙箱化,团队能够说服运营商,Linux 安全标准足以满足需求。接着,团队要求开发者进行身份验证,并利用现有的基础设施和 YouTube 上验证过的政策,确保开发者不会给公司带来不合理的风险。此外,他们还利用众包的力量,建立了一个系统,允许用户报告不良应用,团队会将其下架。最后,他们说服了运营商,正如 T-Mobile 如果遇到网络问题会受损,Google 也会受到影响。Android 和 Google 的声誉都岌岌可危。因此,Android 拥有了所有必要的激励,确保这个系统能够正常运作,确保应用和网络的安全。
对于第二项,Google 为 T-Mobile 定制了一个商店,Nick 称之为“店中店”。实际的应用商店运行在 Google 的基础设施上,但 T-Mobile 被提供了一个主要位置,用于展示他们精选的有限应用集。这样做足以让 T-Mobile 满意,促使他们达成首次发布。然而,最终这个做法消失了;其他运营商并没有在协议中要求这一点,大家也意识到没有特别的理由需要这种要求。所有的工作都由 Google 来管理这个基础设施,而开放的应用商店系统似乎在正常运行。
园墙终于被拆除,Android 成功说服 T-Mobile 同意在平台上开设应用商店。接下来,他们只需要构建它。
Android 的应用商店由服务团队开发,该团队负责 Google 的服务和设备管理。但该团队还聘请了其他人员来研究如何托管和销售应用。这个项目在内部被称为自动售货机。发布时,它被命名为 Android Market。^(2)
拥有一个应用商店一直是计划的一部分。但这个项目启动得较晚,因为当时的首要任务是发布 1.0 版本和 G1。当 G1 发布时,Market 已经上线,但显然还不是一个完善的产品。首先,它被称为 Market Beta。^(3) 更重要的是,用户实际上无法购买应用。相反,所有应用都可以免费下载,价格是……$0。尽管开发者上传应用到 Market、用户下载应用到手机的机制是有效的,但收取用户费用(并支付给开发者)的额外步骤却需要更多的时间和精力。Market 的初始版本对于那些喜欢免费应用的用户来说非常合适,但对于通常希望获得报酬的开发者来说就不太友好了。^(4)
团队引入了来自 Google 支付团队的急需专业知识。Arturo Crespo 帮助搭建了必要的基础设施,使得 Market 能够处理应用的支付功能。当安卓 1.1 版本于 2009 年 2 月发布时,Market 已经具备了销售应用的能力(开发者也因此能够从他们的安卓应用中赚取收入)。
市场在安卓初期是一个吸引人的亮点。上传应用到商店并让它面向日益增长的安卓用户群体变得非常简单。当时,一位在旅行应用领域工作的外部安卓开发者 Dan Lew 表示:“我做了很多傻乎乎的小项目。安卓是一个不错的地方,因为在 Play 商店发布一个几乎没用的应用是相对轻松的。”
但 Market 不仅仅是为了开发者和用户提供便利;它还帮助创造了一个应用生态,令安卓成为一个强大的生态系统,远远超出了人们购买的手机和运行在这些手机上的操作系统。用户不仅能享受到基础的手机和内建功能,还能从几乎无限的应用潜力中受益,随时安装自己喜欢的应用。正是安卓市场帮助创造了这一强大的生态动态,推动了安卓平台的整体发展。
第二十三章:通信
Mike Fleming 和电话通信
有人说,手机不仅仅是用来浏览内容、玩游戏和查看电子邮件及信息的;也有人用它们来打电话。^(1) 至少这是 Android 为 1.0 版本构建通信软件时的理论。
设备通信有两个重要方面:电话通话和消息传递。Android 为这些功能设立了不同的团队。而所谓“团队”,是指每个功能由不同的人负责。
为了让 Android 的电话平台正常工作,团队引入了 Mike Fleming。Mike 对这个领域已经很熟悉,因为他之前在 Danger 编写过电话通信软件。
Mike Fleming 在 2000 年初来到硅谷,加入了一家名为 Eazel 的公司,在那里他遇到了 Eric Fischer(后来的 Android 文本功能开发者)。一年内,Eazel 因资金短缺而裁员,几乎所有人都被裁掉。Eazel 的创始人之一、原 Macintosh 团队工程师 Andy Hertzfeld,帮助许多员工在 Apple 或 Danger 找到了新职位。Mike 和 Eric 来到 Danger。
Danger 最近将产品重心转向了移动电话。Mike 被引入来使电话应用程序正常工作,工程经理认为这会花费几周时间。Mike 说:“我们发现这实际上是进入一整套行业标准和认证的入口。所以它比预期要复杂得多。”
Mike 在 Danger 待了大约四年,然后面试了 Android,那时他已经认识了一些前 Danger 的人。他在 2005 年 11 月加入,并被赋予了让 Android 电话功能正常工作的任务。至少第二次他对这个工作有了更清楚的认识,知道这项任务有多么复杂。
Mike 对接受这份工作有些复杂的心情。“我加入 Android 是因为我真的希望它能存在。但说实话,我并不太想在它上面工作。我做过电话通信的工作,已经有些疲倦了。但总得有人带来这个领域的专业知识。我加入 Google 是为了做 Android,但我没打算待到 Android 1.0 以后。所以我进入这个项目时,心态有点奇怪。”

Dan Bornstein 在一个在家工作的日子里,给 Android 工程团队发了一封主题为“Logcat 阻止我使用键盘”的邮件。(图片由 Dan Bornstein 提供。)
在当时的 Android 状况下,除了电话通信之外还有大量其他工作需要做,因此 Mike 也承担了其他任务。例如,他与 Swetland 一起工作,提高了调试日志的效率,并让开发者更容易访问。在 Android 中,这个系统被称为 logcat,即对日志文件进行 cat 命令操作。
Mike 还帮助了 Java 运行时的工作。Dan Bornstein 当时正在致力于使新的 Dalvik 运行时工作,但团队需要一个占位符以便暂时使用。Mike 引入了 JamVM,一个开源的 Java 运行时。这为团队提供了编写 Java 代码的基础,并且给了他足够的功能来开始编写电话软件的代码,等 Dalvik 运行时工作起来后,他就完成了这部分工作。
电话工作中一个棘手的部分是 G1 手机将配备 3G 连接,而这是 T-Mobile 的新技术。由于 T-Mobile 同时在其网络上实现这一功能,Android 团队需要一种方式来进行测试,于是 T-Mobile 在 Google 园区停放了一个专用的 3G COW^(5),以便 G1 用户可以测试新的网络。

COW #1:这是 T-Mobile 在 Android 大楼附近设置的移动电话塔之一。(图片由 Eric Fischer 提供)
尽管 Mike 使 Android 上的电话功能得以实现,但他并没有参与电话应用程序(也称为拨号器)的开发,尽管他当时确实想做这项工作。曾在 Danger、Be/PalmSource 和 WebTV/Microsoft 工作过的不同派系之间存在深刻的架构分歧。最终,负责工程工作的 Steve Horowitz 介入并达成了一项协议,帮助团队度过了这一冲突和不确定的阶段。Mike 回忆道:“某个时候,我们做出了一个决定,由 Danger 的人负责系统的底层部分,而 Palm 和 Microsoft 的人则负责上层部分。我认为是 Steve Horowitz 与 Brian [Swetland]达成了这个妥协。我记得当时对此并不满意。我不太认同这种做法。但这就是达成的协议。”

COW #2:另一个为测试设置的手机塔(图片由 Eric Fischer 提供)
将 Danger 和 Be/PalmSource/Microsoft 团队进行拆分引发了其他的紧张局势和哲学上的分歧。例如,Dianne 提出了一种Intents模型,Android 通过该机制允许应用程序启动其他应用来处理特定操作,例如“拍照”启动相机应用,或者“发送邮件”启动电子邮件应用。应用程序可以在其manifest文件中注册它能处理的 Intents(manifest 是一个与应用程序捆绑在一起的文件,包含关于应用的概要信息)。将这些信息存储在 manifest 文件中,而不是仅仅存储在应用程序的代码中,意味着系统可以快速识别出哪些应用处理了哪些 Intents,而不需要启动应用程序来查看。
但团队中的其他人并不信服。黄伟说:“当时我们在想,‘为什么要把事情搞得这么复杂?’我记得克里斯·德萨尔沃和迈克·弗莱明主张简单化:只要在应用程序运行时做就行了。有些事情我觉得黛安对平台如何扩展有更深入的理解。但与此同时,我认为活动生命周期^(6)有些复杂。而斯威特兰对事情的复杂性感到非常沮丧。”
迈克·弗莱明补充道:“我认为从来没有真正的讨论平台,去讨论活动和意图的替代方案。我认为这大概是我最不满的地方。作为一个在底层工作的人员,因为我恰好有领域专业知识,也曾在以前的公司参与过上层工作,我非常不满自己无法参与到整个愿景中。”
黄伟观察到:“这些人有很多构建移动操作系统的经验。这并非没有挑战;我们必须弄清楚如何合作,因为我们有不同的看法。而且是非常强烈的看法。总体来说,我认为我们设法解决了这些分歧。并不是所有分歧都解决了,因为迈克·弗莱明离开了。”
2008 年春天,在 1.0 发布前的六个月,迈克离开了安卓。他说:“产品很难凑合在一起。我感觉完全有可能它无法发布。它在设备上表现不好,运行很慢,而且经常崩溃。它足够用了,但我发现这是一个非常令人沮丧和失望的产品。”
“电话功能掌握在了合适的人手里。Dalvik 相关的工作也在合适的人手里。我觉得我已经没有任何可以做的事情来帮助它发布了。我没有预料到自己会待到完成后。我看不出自己能做些什么来帮助完成它。所以我离开去加入了一家创业公司。”
尽管迈克当时对安卓的看法不佳,他在离开之前已使电话功能得以实现,且产品继续朝着 1.0 版本迈进。
黄伟与消息传递
最近安卓版本的用户可能会对谷歌最近推出的众多消息传递应用感到疑惑,但安卓一直以来就有许多这样的应用。从某种程度上说,这种现象是因为有如此多种类的消息传递方式:短信(通过运营商发送文本消息)、彩信(发送图片或群聊)、即时消息(各种不同的类型)、视频聊天等等。即使在早期,也有多种方式进行消息传递,大多数使用不同的底层协议,并且需要不同的应用程序,但只有一名工程师负责所有这些应用:黄伟。
2006 年春天,魏加入了 Android 浏览器团队,但在多年从事浏览器工作的经历之后(先是在微软,然后是 AvantGo,再到 Danger,最后是 Android),他已经准备好迎接新的挑战。Steve Horowitz 建议他接手消息传递功能,因为 Android 需要这个功能,而当时没有其他人负责这个任务。于是,魏开始参与 Google Talk 应用和短信(SMS)的开发工作。
拥有这两个应用似乎对一个工程师来说是一个庞大的工作量(事实上,现在多个团队的成员在开发类似的应用)。实际上,这些应用的底层机制是完全不同的,特别是短信(SMS)消息传递所需的运营商要求。但在 Android 的早期,这种工作量是很常见的。魏表示:“那时候,我们甚至没有每个功能分配一个工程师的奢侈。其他人可能负责一到两个应用。”
魏首先深入研究了 Google Talk,并且很快就能使演示版应用运行起来。促使这一进展的一项因素是,Google Talk(作为一个已经存在的桌面应用,并且在 Google 服务器上有完整的后端支持)使用了一种功能非常齐全的消息传递协议(XMPP^(7)),因此魏能够相对简单地编写应用程序,通过该协议建立与服务器的连接,并进行消息的双向传输。
将他的应用从演示版转变为产品的一大难点是如何保持服务器和客户端之间的连接。这种连接经常会掉线,但客户端并不会立即发现,仍然继续发送消息,而没有意识到消息实际上并没有成功发送。魏花了大量时间在项目中,致力于让连接更加稳定,设计了处理掉线和重试的逻辑。
当系统的基本功能开始运作时,负责服务团队的 Michael Morrissey 建议将这个连接用于所有 Google 应用(包括 Gmail、联系人和日历)。这样,所有这些应用就不需要各自维护与后端的连接,而是可以共享这个单一的、持久的连接。设备上的软件会将各应用的数据合并,通过这个连接发送到服务器,并从服务器接收响应,将其传递给相应的应用程序。这与 Michael 曾经在 Danger 参与设计的架构相似。
这个连接不仅对现有应用程序可用,还可能用于推送其他应用的消息。Charles Mendis 的 Bounce 应用希望能够在朋友位置变化时通知地图应用。通过这个持久连接启用推送消息功能,地图服务器就能够得知位置变化,并将更新发送到设备,设备再将其传递给地图应用,以更新屏幕上的位置。
Wei 与 Debajit 合作实施这一功能,将所有基础设施搭载到现有的 Google Talk 连接上。他们希望在 1.0 版本中发布这一功能,作为不仅仅用于 Google 应用的连接,也能供任何想使用推送消息的应用使用。但后来他们与安全团队进行了讨论,安全团队告诉他们:“你们不可能发布这个东西。”它不够安全。
尽管推送消息的功能和 API 在 1.0 版本之前的发布中已经对开发者开放,但它在.9 版本中被移除了。关于这一点在 Android 0.9 SDK Beta 发布说明中有提到:^(8)
由于接受来自设备“外部”的任意数据存在安全风险,GTalkService 的消息传递功能将不会出现在 Android 1.0 中。GTalkService 将提供与 Google 服务器的连接,用于 Google Talk 即时消息传递,但该 API 已从此版本中移除,以便我们改进该服务。请注意,这将是一个 Google 特定的服务,不属于 Android 核心的一部分。
这个功能后来进入了 Android(在团队修复了安全问题之后),最终作为 Google Cloud Messaging 出现在 Google Play 服务库中。^(9)
短信(SMS)
与此同时,Wei 也在努力让 SMS 功能正常工作。该项目的大部分工作集中在实现和完善所有复杂的功能和要求,以便通过运营商认证。他说:“这很痛苦,因为运营商的问题。”
很长一段时间里,Wei 都是独自工作。但随着 1.0 版本的临近,Android 团队与来自中国 Esmertec 的工程师合作,尤其是帮助集成 SMS 和 MMS 并确保它们符合运营商的要求。
Ficus 曾负责摄像头和音频驱动的工作,他也加入了这一努力,帮助让它更加可靠。他个人热衷于改善 Android 上的消息传递功能。“我试图做一个好的 Android 内部用户^(10),我在发短信……但它就是不行。我觉得年轻时的视角让我看到了一些其他地方缺失的东西;这是 2000 年代中期社交生活的一个重要部分。我开始修复 bug,提交代码。我没有得到任何允许停止我其他工作的授权,也没有获得开始做 SMS 的批准,我只是做了。我感觉应该有人去修复它。”
另一位参与帮助的人是 Peisun Wu^(11),他负责管理该项目(除了其他 Android 项目)。从外部承包商到运营商测试,有许多细节需要管理。
运营商测试使得像这样的通信项目变得复杂。榕解释道:“有很多运营商合规认证的事情,这让我疯狂。尤其是 MMS 标准非常复杂。你可以用它做很多事情,比如制作幻灯片、图像动画和播放声音。尽管大家都知道,实际上任何人最想做的事情就是只发送一张图片,但你必须实现所有功能,因为必须通过运营商认证。”
2008 年 6 月,榕、魏和佩孙飞往中国与承包商合作。四川刚刚经历了一场大地震,他们在北京见面,并在谷歌办公室工作了两周。

2008 年 6 月,魏和榕在北京旅行期间(图片由佩孙·吴提供)
榕记得后来一次与同一团队合作的旅行:“2008 年夏天,尝试发布。所有的原型设备都不能离开谷歌员工的监督。所有承包商都在中国成都。我们之前在北京见过面,但那时候正值奥运会,我们无法找到合适的地方开会。我们得找到一个有 GSM 网络和谷歌办公室的地方,这样我们才能带着这些测试设备,并且工程师们能获得签证。因此,我们在苏黎世待了两周。”
谷歌 Talk 和短信(带 MMS)都及时赶上了 1.0 版本的发布。
第二十四章:开发者工具
开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者,开发者。
— 史蒂夫·巴尔默,微软^(1)
Android 成长的原因之一是一路上创建的开发者生态系统,这使得成千上万(现在是数百万)的应用程序得以让人们找到、下载和使用。
但这种生态系统并不是自动就能形成的,尤其对于一个没有市场份额的新平台。为了降低应用开发者的入门门槛,使他们能够更轻松地编写和发布应用,Android 需要为开发者提供工具。
一个有决心的开发者可以编写代码并使用一些晦涩的命令在终端中将代码编译成应用。如果这个开发者只是想写一个“Hello, World!”^(2) 程序,那可能只需要这些。
但任何真正的应用程序都涉及大量的代码和其他材料,包括多个文件、图像资源、文本字符串等。如果你只能在文本编辑器中手动编写代码,并且仅有一个命令行编译器作为工具,那种复杂性会让人不堪重负。
这就是为什么 Xavier Ducrohet 于 2007 年 4 月加入团队的原因。
Xavier Ducrohet 与 SDK
Xavier(大家叫他 “Xav”)一直在从事工具开发工作。最近,他在 Beatware 开发绘图工具。这并不是一份最稳定的工作:“我们并不总是按时拿到工资。”但 Xav 的绿卡还在处理中,这让他不得不再待一段时间,离开公司可能会影响绿卡处理进程。另外,他感到有责任不让这家公司陷入危机。“如果我离开了,公司就完了。”
Beatware 最终于 2006 年底被 Hyperion Software 收购。Xav 决定再坚持一段时间,因为他还有一些股票还在归属中。但在 2007 年 3 月,Oracle 收购了 Hyperion,这一切就结束了;Xav 不想加入 Oracle。他联系了在 Google 的老朋友 Mathias Agopian。
尽管该项目是保密的,Xav 已经对 Android 有了很好的了解。Beatware 曾早期与 Android 进行过交流,提供一些图形技术。Beatware 提供了一款基于矢量的图像编辑工具,Android 本可以用来处理 UI 图形。矢量图像的优势在于,在缩放时比纯位图图像表现得更好,因为位图图像在缩放时会变得模糊或失真。但 Android 最终开发了自己的一种图像格式,称为 NinePatch。^(3)
Xav 已经认识 Mathias 好几年了,来自 Be 社区。Xav 在法国上大学时曾玩过 BeOS。那时,他在巴黎认识了 Be 社区的人,包括 Mathias 和未来的 Android 工程师 Jean-Baptiste Quéru。所以,当 Xav 想换工作时,他联系了 Mathias。他之前已经在 Beatware 公司面试过这个团队,所以这次的面试只是和 Steve Horowitz 一起吃午饭。他在 2007 年 4 月三周后开始工作。
在第一天,Xav 和 Steve 及 Mike Cleron 坐下来,Mike 建议他从工具入手。首先,Xav 深入研究了 DDMS^(4)。DDMS 是一个在开发者桌面系统上运行的工具,它是许多不同工具的容器。例如,DDMS 提供了一个当前正在运行的 Android 设备上的应用列表。选择其中一个应用后,该应用会连接到主机计算机的 8700 端口,此时你可以通过调试工具连接该端口来调试这个应用。
Xav 的初始项目^(5)是使 DDMS 能够可视化本地内存。对于大多数 Android 开发者来说,这并不是一个特别关键的需求,但对当时的 Android 平台团队来说,这非常重要。在完成该项目后,他将庞大的 DDMS 工具重构为独立的几个部分,包括核心功能、用户界面层和将其他两部分连接起来的粘合层,形成一个独立的工具。
通过重构 DDMS,Xav 能够将现有的开源开发 IDE Eclipse 与其连接起来。到 6 月时,他能够向更大的 Android 团队演示整个工作流程:在这个 IDE 中打开应用项目,编译它,部署到模拟器上,在模拟器上运行,停在代码中的断点^(6),然后逐行调试代码。
这个项目很好地展示了 Android 上的工作方式。有人发现了问题,然后快速地解决它。Xav 在 4 月下旬加入。到 6 月,也就是他加入两个月后,他向团队演示了全新的功能工具流程。这套工具在几个月后随着 SDK 的发布交付给了外部开发者,并成为 Android 开发工具链的基础,持续了很多年。他从加入公司和团队时对 Android 一无所知,到仅仅几个月后提供了一个为所有 Android 开发者(平台和应用程序,内部和外部)提供基础支持的工具。

2007 年 11 月 12 日,Xav——第一个 SDK 发布日(图片来自 Brian Swetland)
Xav 完成那个 IDE 项目后,他创建了安卓的 SDK。SDK 是一个可安装的工具包,包含了为应用开发者准备的工具和其他组件,其中包括 Android Eclipse 插件(以及所有的子工具,如 DDMS、ADB 和 Traceview)和 Android 本身。Android 部分包括开发者编写程序时所依赖的代码库,运行在模拟器中的安卓系统镜像,以及文档,帮助开发者搞清楚他们该做什么。同样,Xav 识别到了需求并将各个部分组合起来。幸好他这么做了。这项工作大约在 2007 年 8 月完成。同时,安卓的 SDK 计划在 11 月发布,因此他们有了一些可以发布的东西,真是太好了。
David Turner 与模拟器
开发人员在平台开发初期所需的关键工具之一就是运行该平台的设备;如果你无法运行应用程序,怎么能验证它是否按预期工作呢?
但是,当安卓首次开发时,能够运行该平台的设备几乎不可用,^(7)于是团队找来了一位写虚拟设备的人:David Turner(团队称他为“digit”)。
在编写原始的安卓模拟器之前,David 在编程圈子里以 FreeType 字体渲染库的原始作者而闻名。关于谷歌的一个迷人之处在于,许多公司里的员工都因做某一特定事情而出名……而这些事情与他们在谷歌做的工作完全无关。我认识一些著名的经典游戏开发者、基础图形算法的发明者和 3D 图形专家,他们都没有在谷歌从事与他们曾经取得的成就相关的工作。
其他公司雇佣人是因为他们做过的事情,然后要求他们做更多相同的事。而谷歌雇佣人是看中他们是谁,然后要求他们做任何需要做的事情。过去的经历是他们能力的一个好例子,但在谷歌眼中,这并不会限制他们能做的事情。这就是谷歌如何发现拥有世界级字体渲染专家的原因,他正从事安卓模拟器的工作。
David 从小就学会了性能编程,当时他在 Apple II+上用 BASIC 和汇编语言编程,并在过程中领悟到性能编程的重要性。“这些机器性能如此有限,每一个细节都很关键,要从中得到令人满意的效果。”
几年后,他开始使用一台运行 OS/2 的计算机,但不喜欢它所使用的字体,于是他给自己设定了一个挑战:他根据 TrueType^(8)字体规范,尽可能少地使用内存和代码编写了一个渲染器。最终结果就是 FreeType 渲染器。他将其作为开源项目发布。它受到了广泛关注,并被广泛应用于有限的嵌入式系统,从电视到相机再到…Android。FreeType 是(并且仍然是)Skia 的字体渲染器,Skia 是 Android 的图形引擎。
2006 年,Android 团队的一名工程师(该团队一直在寻找嵌入式程序员)在 FreeType 的源代码中看到了 David 的名字并联系了他。“当然,没有人告诉我为什么 Google 联系我,所以我准备面试时读了大量关于 HTML、SQL、网页服务器和数据库的资料。令我惊讶的是,所有面试问题都涉及基础的数据结构、算法和嵌入式系统,因此面试进展得比我最初预期的要顺利得多。”
David 在 2006 年 9 月加入了 Android 团队。
David 的第一个项目是为 C 编程语言建立并运行一个工具库。^(9) 当时,Android 使用的是一个非常小且基础的 C 库,但它缺乏一些必要的功能,并且拥有比最终开源平台更为限制的许可证。David 将 Android 的“Bionic”库从各种许可证兼容的 BSD^(10) Unix 库中汇总,并结合新的代码以集成 Linux 内核,支持 Linux 或 Android 特有的功能,这些在 BSD 代码库中是没有的。
在完成这项库的工作后,David 继续进行模拟器的开发。
最初,Android 有一个模拟器,这是一个在开发者的桌面电脑上运行的程序,模仿 Android 设备的行为。但模拟器会伪造许多细节;它们模仿系统的外部行为,却忽略了内部的许多细节,这意味着整体系统的行为并不符合实际设备(因此不能依赖于它进行真实测试)。
Fadden 编写了最初的模拟器,但当 Android 处于不断变化中时,他逐渐厌倦了维护它。David 记得,“它由唯一的一名工程师维护,每次我们添加新特性时他都会感到疲惫不堪。我们的计划是:模拟器基本上已经死了,我们需要一个好的模拟器。”
Android 已经有了一个初步的模拟器,基于一个名为 QEMU 的开源项目,该项目由 David 的朋友 Fabrice Bellard 创建。David 对这个实现进行了彻底改造:“当时我们使用的是一个非常旧的 QEMU 版本,这个版本被修改得相当激进。没有人完全理解发生了什么。”David 从拉取一个更新的 QEMU 版本开始,尽管这个版本也有自己的问题。“当时(大约 2006 年到 2010 年),QEMU 的开发状况相当糟糕。完全没有单元测试,全球变量^(11)到处都是。”
他最终让系统运行得更好,但仍然有很多工作要做,比如让基于 Linux 的 QEMU 项目能够在 Windows 和 Mac 上运行,并将模拟器中特定于 Android 的部分分离出来,以便进行更好的测试。
当时,模拟器至关重要。硬件设备非常难得。拥有一个模拟器,它能够模拟真实设备的功能,使得(Android 团队的开发者,最终是外部开发者)能够编写和测试他们的 Android 代码成为可能。
模拟器就像一台真正的设备,因为它模拟了真实设备上发生的所有事情。它不仅看起来像一部 Android 手机(在你的桌面计算机上的一个窗口中),而且内部运行的每一个比特,直到芯片级别,和实际硬件设备上的完全相同。
模拟器的另一个优势是速度,相对于实际的硬件设备(对于有设备的开发者)。与主机上的模拟器通信比通过 USB 电缆与真实设备通信要快得多。将应用程序或整个 Android 平台通过 USB 电缆传输可能需要几分钟,而将代码推送到模拟器(它运行在同一台计算机上,代码也是从这台计算机推送的)则要快得多,因此工程师可以使用虚拟设备而不是实际设备时更具生产力。
另一方面,模拟器一直因其极其缓慢而受到批评,尤其是在启动时,启动模拟器的过程模仿了手机启动,因为它精确地模拟了手机启动时的每个步骤。你可以在大多数情况下让模拟器保持运行,特别是在纯粹的应用开发中。但模拟器的启动和运行性能,直到最近的版本发布,仍然是常见的抱怨来源。^(12)
模拟器项目也是 Android 在早期阶段,呃,坚韧不拔精神的伟大展示。并不是说团队很小……实际上甚至没有团队。负责这项庞大工作的只有一个人,而模拟器只是他参与的多个项目之一。
David 多年来一直独自开发和维护模拟器,这只是他工作中的一部分。
Dirk Dougherty 的文档:RTFM^(13)
即使拥有全世界最好的工具,也无法帮助开发者编写代码,如果他们不知道该写什么的话。开发者在某个时候需要了解系统以及如何将各种组件组合起来,以便创建应用程序。他们需要文档。
对于 Android(以及许多其他平台)来说,“参考文档”往往是由编写 API 和底层功能的工程师来编写的。也就是说,如果一位工程师添加了一个名为 Thingie 的类,那么他们会(或应该^(14)) 编写一种概述文档,说明这个类的用途以及为什么开发者应该关注它。Thingie 类中的函数也会(或应该)有文档,描述何时以及如何调用这些函数。
但参考文档只能帮你走到一定程度。能够查阅文档,了解如何使用例如 Activity 类,固然很棒。但是你是怎么学会足够的知识,甚至知道要查找 Activity 的呢?开发者们真正需要的,特别是对于像 Android 这样的新平台,是一些更高层次的文档,提供概述并教授基础知识。这个平台是什么?我们如何为它编写应用?在哪里可以找到示例代码,看看是如何做的?
Android SDK 将在 2007 年 11 月发布。在此之前的三个月,团队决定他们需要一位技术写作人员,并请来了 Dirk Dougherty。
Dirk 曾在 Openwave 工作,那是一家为手机开发浏览器的公司。一位前同事将他的简历转发给了 Android 团队。Dirk 参加了面试,并在几周后开始了工作。
“我来到 44 号楼,找到了我的办公桌。它在大厅旁边的一间会议室里,后来那间会议室成为了游戏区。^(15) 房间里堆放着一堆空的桌子。我不知道发生了什么,也不确定我是不是在正确的地方。最终,Jason、Dan、Dick、David 和 Quang 进来了,他们正组建即将成为 DevRel^(16) 团队的成员。我们都搬进了那里,开始学习这个平台。有人在我们的白板上画了一个倒计时日历,显示 SDK 发布的天数,从那时起我们就开始朝着发布目标推进。”
Dirk 和 DevRel 团队整理了 SDK 所需的各个部分。“第一年我们基本上是在不断冲刺,搭建网站,完成基本的文档编写。大部分是参考文档和工具,再加上一些指南和 API 教程。随着平台稳定,我们发布了持续的预览版本和 SDK 更新。由于开发者挑战赛和开发者们的强烈兴趣,我们需要扩展文档。我得到了一个我曾合作过的外部作家的帮助,^(17) 他与我合作撰写了 Android 基础文档,解释这些东西是如何工作的。几个月后,我们得到了更多的增援,另一个内部作家 Scott Main 加入了我们的工作。我们把所有的时间都花在了围绕参考文档构建基础文档,然后再搭建网站。整个工程团队也给予了我们巨大的支持。项目启动是一个完全的团队合作过程。”^(18)
第二十五章:精简代码
一旦你写完了,就无法再回去重新优化。
—Bob Lee
Android 从最早期开始的一个特点就是它经过了极其优化,以便能在当时那些极其受限的移动设备上运行。团队的性能思维影响了从 API(许多 API 是以特定方式编写的,以避免分配内存)到给外部开发者的编码建议的一切。这一切都围绕着编写最优代码,因为每一个周期,每一千字节,都消耗着宝贵的资源或电池寿命,这些本可以用在其他地方。
至少部分性能优先的关注可以归因于早期团队成员的背景。那些曾经在 Danger 工作的工程师们,他们让操作系统能在比 Android 的 G1 更为受限的设备上运行。而来自 PalmSource 的工程师们也熟悉移动设备的限制和现实。
Bob Lee 观察到,“他们(前 PalmSource 工程师)曾说,其中一个失败的原因是他们试图做的事情超出了硬件的承受能力。一旦你写完了代码,就不能回头再做优化了。我只是觉得他们在 Android 上避免了那个错误。这也是为什么黛安(哈克伯恩)和其他人对性能如此严格,一直微优化许多细节的原因。那时候的手机速度是如此慢。”
“我记得大家——我、黛安、丹(博恩斯坦)——都会待在这个战争室里,因为在发布的过程中,总会有很多地方因为使用过多内存而出现问题。我们没有交换分区,因为没有意义去设置交换分区。程序会因为内存不足而崩溃。那是一次次的英雄般的会议,我们有时会持续几天,而你永远不知道什么时候会结束,就是不停地努力解决内存问题。”
“这一切都与内存页的分配有关。黛安或者布赖恩·斯韦特兰曾写过这些工具,用来查看脏页以及哪些页面被访问过。我们只是必须解决这个问题。我们需要不断查看哪些应用程序引发了问题并尽量定位它们。”
Ficus 回顾他在 Be 和 Danger 的经历对他在 Android 工作时的影响:“我们当中很多人都来自嵌入式系统,拥有对 CPU 周期或内存极度节俭的哲学。我觉得从这个角度来看早期 Android 的许多决策是很有趣的。我看待这些工程师,就像他们是在大萧条时期成长的,他们学会了如何从锅底刮食物。”
整个平台团队的思维方式是性能优先。这源于早期设备的内存有限、CPU 速度较慢、没有 GPU 渲染(直到 Honeycomb 版本发布,Android 才开始使用 GPU 进行 UI 图形渲染),以及 Dalvik 的垃圾回收器(需要时间进行内存分配和回收)等因素的综合影响。即使今天每个设备的性能都更强大、更快速,这种态度在内部依然延续着。手机的每一项操作都会消耗电池电量,因此优化平台代码依然是值得的。从那些早期的日子开始,外部开发者的建议要求已经放宽,但 Android 的 API 和实现仍然反映了当初的性能限制。
第二十六章:开源
我认为开源的事情并不重要。
—Iliyan Malchev^(1)
对许多人来说,开源有很多种意义。
它可以是一种“众包”工作的方式,借助更大的社区来帮助完成任务。Linux 就是一个很好的例子。尽管最初的系统是由单个开发者 Linus Torvalds 编写的,但在随后的几十年中,许多个人和公司都贡献了从修复到驱动程序再到核心系统功能等各个方面的内容。
开源可以是一种宣传和分享工作的方式。GitHub 是一个很好的平台,托管着许多活跃(也有过时的)项目,展示了那些花时间和精力完成并上传代码,而不是让它在本地系统中搁置的人们的作品。开源你自己的宠物项目可以是一个很好的方式,让别人知道你是一个从事这类工作的开发者;能够指向一个公开透明的网站是向潜在雇主展示你能力的好方法。
开源可以成为公司的招聘工具。类似于个人宣传自己能力的方式,公司也经常开源项目(应用程序或供其他开发者使用的库)作为将公司名字推向其他开发者的一种方式。Square 本质上是一家信用卡公司,单靠他们的业务吸引开发者可能比较困难。但他们在开发者社区中因提供有趣且强大的开源库而广为人知。那些对金融交易软件不感兴趣的开发者也会去那里,因为他们希望为开源社区做出贡献(包括在这些项目中作为开发者让自己的名字广为人知)。
开源也可以是大公司悄无声息地淘汰某个产品的方式。有时候公司决定关闭一个项目,并将那些工程师调到一个更有前景的项目上。公司可以,也经常会,直接终止该产品。但他们也可以将旧代码开源,作为对开发者社区的一种馈赠。公司通过这种方式并不会直接获得利益(事实上,通常需要一些努力和时间将项目迁移到开源),但通过这样做,他们可以赢得开发者的好感,并减轻关闭那些开发者正在使用并依赖的产品带来的痛苦。
开源也可以是一种让其他人透明地获取并使用你的软件的方式。这就是 Android 的开源模式。
自 2008 年 11 月起,所有 Android 平台软件都可以作为 Android 开源项目(AOSP)在source.android.com/上获取。每个版本的代码都会在该版本发布的同时开源^(2),并提供给设备使用。只要新版本对用户开放(无论是新设备还是现有设备的更新),开发者就可以查看用于创建该版本的代码。
Android 接受外部贡献;开发者可以在source.android.com/上创建账户并提交补丁^(3)。这些补丁会由 Android 团队成员审查,审核通过后可以提交到 Android 源代码库中,以供未来版本使用。
事实上,外部贡献并不常见……也不是预期中的情况。Android 确实会收到一些合作伙伴公司的定期贡献。例如,合作伙伴通常会修复 bug,以确保他们的设备能正常运行。也许他们发现了一个可以改进的边角案例,或者 Android 尚未考虑到的设备外形,或者他们仅仅是发现并修复了一个 bug。对他们来说,将修复直接集成到 Android 中是有意义的,这样每次 Android 发布新版本时,他们就不需要重新应用这个修复。而 Android 偶尔也会有一些个人贡献修复。但外部贡献仍然很少;大部分代码都来自于内部工程团队。
这种动态背后有几个原因。一方面,Android 的源代码库非常庞大,即便是一个简单的修复,也需要投入大量的精力来理解原始代码的上下文以及该修改的影响。更重要的原因是 Android 的“最终开源”^(4)模式本身。外部开发者无法得知,当他们发现并修复了一个 bug 时,是否该 bug 已经在内部/未来版本的代码中修复,甚至他们所专注的那一段代码是否仍然存在。代码有时会因为未来的需求或变更而被移动或重写。
即使 Android 没有从外部获得大量的贡献,Android 的开源模式仍然带来了显著的优势。首先,应用程序开发者喜欢它。一个像 Android 这样规模和复杂性的平台永远无法被完全文档化,以便程序员能够理解它的每一个细微之处以及内部的互动方式。直接查看实际代码以确定到底发生了什么是非常宝贵的;如果开发者可以查看代码本身,他们就不需要猜测平台在做什么。这种透明性一直帮助 Android 开发者编写他们的应用程序,这也是 Android 与许多其他操作系统平台之间的根本区别的体现。^(5)
Dan Lew,一个在 Android 初期在小型初创公司开发 Android 应用的开发者,说代码的开放性简化了开发过程:“早期有很多平台的 bug 要处理。我记得有很多的 hack。但由于 Android 是开源的,通常这些 hack 至少是可以发现的。如果它不是开源的,要解决一些问题就会困难得多。”
Android 开源模式的第二个,也可以说是更重要的元素是,Android 的合作伙伴可以自由轻松地访问所有内容。这实际上是 Android 开源平台的最初原因;这是一种机制,可以让任何潜在的设备制造商获取他们所需的一切,从而使 Android 可用。没有许可证,也没有冗长的合同谈判;合作伙伴可以简单地访问网站并获取他们需要的组件来制造基于 Android 的设备。通过这样做,他们有助于实现一致的兼容 Android 实现的生态系统,因为每个人都从相同的公共实现开始。如果他们想要获取像 Play Store、Maps 和 Gmail 这样的 Google 服务,那就有更多内容,但用于构建手机平台的核心代码可以供任何人下载和使用。Romain Guy 解释道:“这就是我们在谈论 Android 的‘开源’时的想法。合作伙伴并不一定关心贡献,但他们拥有他们所需的一切。”
Brian Swetland 认为:“Android 的一个目标,在他们与 Google 有任何接触之前,就是为人们提供一个选择,避免某个单一公司主导移动计算平台的可怕未来。他们的想法是,如何让人们采用它?它必须是开放的。否则,他们怎么能信任他们拥有任何程度的控制权呢?”
Dianne Hackborn 也表示同意,并将 Android 的开源模式与她之前所经历的授权模式进行了比较:“我们在 PalmSource 时遇到的一个问题是,其他公司对使用我们的平台非常害怕,他们害怕移动领域会重蹈微软当年对 PC 做的事情。例如,摩托罗拉曾对授权使用 Rome(PalmSource 为 Palm OS 6 开发的 UI 工具包)感到非常困难,但他们对收购公司并拥有它却毫不犹豫。能将 Android 做成开源,使得 OEM 更容易接受,因为他们可以共享一部分所有权,并且它的灵活性也使得移动设备能够快速演进。”
正是这个第二个元素——为设备制造商开放平台——使得 Android 与其他平台产品区分开来。这个平台不仅可以使用,而且其代码也可以理解和修改,随着公司将其应用到设备中。此外,这个开源平台本身也是一个完整的、符合生产标准的实现,已经在实际硬件产品上验证,并且可以供制造商使用。
相比之下,如果你当时想要发布一款 Windows 手机,你必须向微软购买 Windows 授权(并支付费用)。此外,将它应用到新设备的过程也非常复杂。Michael Morrissey 在 Android 之前曾在微软工作,亲眼目睹了这个过程。“当你试图在一款新手机上启动新的操作系统,无论是 Win CE、Pocket PC 还是其他什么系统,整合这些东西并调试其运行是极其痛苦的。你需要有一个叫做‘板级支持包’的东西,它包含了来自 OEM 的所有底层代码。然后,你还需要所有更高层的 Windows 代码。所以如果电话功能失败,或者网络不好,或者出现其他问题,问题出在哪里?没有人能弄明白。”
“这是我在微软时最喜欢的一个玩笑:有一个团队专门负责与这些 OEM 合作,推动新硬件的开发。可问题是,双方都不能看到对方的代码,因为它是保密的。三星、HTC 或其他公司会派人到西雅图,坐到这个团队的成员旁边。他们会尽力调试,而不让彼此看到对方的代码。他们只是凑过去说,‘这是我认为我在这个调用中发送给你的内容,你看到什么了?’这就像是一场冗长而荒谬的舞蹈。”
当然,Android 开源的事实意味着制造商可以免费使用它,这是一个额外的好处。Michael 说:“这些 OEM 厂商的利润率非常低。所以,如果你有像 HTC 这样的公司,他们每台设备要被微软收费 10 美元,并且为了让它工作,他们还得做大量复杂的集成工作,那么免费的开源就是魔法。如果你有像 Android 这样开源的系统,那么 OEM 厂商可以非常非常快地推出新设备,因为他们可以访问所有的代码。更重要的是,它是免费的。”
另一方面,如果你想要发布一款基于 iOS 的设备……你是做不到的。苹果是唯一的 iPhone 制造商;他们根本不提供其平台。类似地,RIM 是唯一的 BlackBerry 设备供应商。与此同时,Android 不仅是免费的,而且任何人都可以自由地下载、玩耍、定制并在此基础上开发。
事实上,这种模型也使得软件对应用开发者来说很容易查看内部代码,并且使得接受任何外部(尽管是偶尔的)贡献成为可能,这仅仅是一个意外的巧合,最终对 Android 有利。
当然,开放源代码不仅仅是说代码是开放源代码。团队必须以一种方式将项目组织起来,使得外部开发者和公司能够访问、下载、构建并理解如何做到这些。在初始发布之前的那段时间里,团队花费了很多努力来整理这些内容。
首先,源代码本身必须组织成一个适合持续向开源分发的状态,这是 Dave Bort 在 Ed Heyl 团队中努力的成果。
Google 开源项目主管 Chris DiBona 也参与了解决这个问题。Android 当时使用的一些工具不适合外部使用。Google 使用的工具要么是授权工具,要么是内部开发的专有工具。Android 的代码需要能够由外部开发者在没有专有或授权工具的情况下进行构建,因此团队内部采用了可以(免费)供外部使用的工具。
Chris 帮助做出了将源代码管理^(6)切换到一个名为 Git 的系统的决定,但这个系统在大多数工程师中并不受欢迎。Chris 对他们说:“内核和系统团队[已经在使用 Git],他们永远不会离开 Git。Git 是我们开发模型的正确选择。他们需要一个外部的人来讨厌。我自愿成为那个人。”
团队做出了改用 Git 的决定,代码也被组织成适合公开使用的形式,并且该项目于 2008 年 11 月在 1.0 版本发布时开源。此后,它一直保持开源状态,为开发者提供了透明度,为制造商提供了平台代码。
加入安卓团队的 Jeff Sharkey 总结了开源对合作伙伴和用户的吸引力:“我坚信开源软件,因为它赋予人们建造你从未想象过或没有资源自己建造的东西的力量。如果你是安卓初期的 OEM 厂商,你无法授权 iOS,而微软提供的体验也相当统一。相比之下,安卓为 OEM 厂商提供了一个机会,可以迅速添加功能,从而在商店货架上与众不同。”
“开源世界的精神也引起了终端用户的共鸣。安卓不是像独裁者一样强制规定只能有一个主屏幕应用、一个软件键盘、一组快捷设置图标等,而是让用户彻底自定义它们。手机是非常个人化的设备,这些更深层次的定制(不仅仅是外壳)使用户产生了更强的连接感和拥有感。”
本章开头引用了伊利安·马尔切夫(Iliyan Malchev)的一句话,虽然这句话被残酷地断章取义了。以下是完整版本:
“我不认为开源这个事情很重要。我们本可以在不开源的情况下免费提供给他们。我是开源的倡导者。我认为我们应该做更多的开源工作。但我就是不认为安卓的强大取决于它是否开源。如果我们在没有开源的情况下让它免费,它同样会如此成功。”
也就是说,拥有源代码并不是开源的关键部分;仅仅将源代码公开就足够了。开源只是实现这一目标的自然且透明的方式。
第二十七章:管理所有事务
本书的其他章节大多是为了讲述 Android 是如何一点一点建立起来的,以及那些将这些碎片拼接在一起的人们的故事。但有一些帮助推动项目进展的人,并没有负责单独的某些部分;他们负责的是整体的努力。欢迎来到 Android 的“商业”层面。
安迪·鲁宾与 Android 管理
安迪·鲁宾对机器人的兴趣从他职业生涯的起点就有了,当时他在卡尔·蔡司公司从事机器人工作。后来,他加入了苹果公司,并获得了“Android”的绰号。此后,他在 WebTV 工作,那里有其他未来的 Android 团队成员,迈克·克莱龙记得他是“走廊里那个玩机器人、疯疯癫癫的家伙”。
在 WebTV 之后,安迪创办了 Danger,最终成立了一家名为“Android”的初创公司。
虽然安迪一直在领导 Android,无论是在谷歌收购之前还是之后,但他通常让其他人管理团队成员。克里斯·怀特在前六个月领导工程工作,并且还参与了系统架构和设计的工作,但最终,史蒂夫·霍罗维茨被引入来管理日益壮大的团队。史蒂夫离开后,约 1.0 版本左右,广志·洛克海默接管了工作。安迪依赖这个管理层来处理团队中的人事问题,而他自己则专注于项目的商业层面,比如合作伙伴会议。
安迪在 2013 年初参加巴塞罗那的世界移动大会时离开了团队。广志讲述了他和特雷西与安迪一起参加的一系列合作伙伴会议:“就是在那个时候,他决定告诉我们他要离开。那是在与 LG 的会议之后、与三星的会议之前。我们有一个 15 分钟的休息时间。他已经在某个休息时告诉了[特雷西],我完全没有察觉。把大家都赶了出去。就剩下我和安迪了。他说,‘我做这件事已经 10 年了,我累了,我要离开了。’”
特雷西·科尔与 Android 管理
在安迪·鲁宾离开后,负责顺利过渡的人员之一是特雷西·科尔。特雷西曾是安迪的行政助理,已经工作了 14 年,在安迪离开时,她是 Android 的首席行政人员。她了解如何在 Android 和谷歌中推动事情进展,而且她并没有打算离开。
2000 年 8 月,特雷西·科尔在一家生物技术公司担任行政职务,并希望辞职。一个朋友建议她去找他朋友安迪,安迪当时在 Danger 工作。她与安迪和 Danger 的其他创始人(Joe Britt 和 Matt Hershenson,他们后来也加入了 Android 团队)进行了面试,最终成为该团队的行政人员。2003 年安迪离开 Danger 时,特雷西留了下来,但继续在旁协助他。随后,在 2004 年秋季,她加入了安迪的初创公司——Android,并与布莱恩·斯威特兰德同一天开始工作。
当 Google 收购 Android 时,Tracey 与团队其他成员一起加入了 Google。她知道他们正在与 Google 接洽,但并不清楚进展到何种程度,“我记得他见了 Larry,他们很投缘。我去度假,回来后突然发现我们将要在 Google 工作了。”
Tracey 继续在 Google 担任 Andy 的助手,并领导 Android 的行政团队,直到 2013 年他离开了 Android。到那时,她继续担任管理整个 Android 团队的角色,并领导项目中的其他管理员,同时也成为了弘志的助手。
弘志·洛克海默与合作伙伴
弘志·洛克海默(Hiroshi Lockheimer)刚到 Google 时,负责管理合作伙伴公司,与 OEM 厂商和运营商合作,将 Android 系统移植到他们的设备和网络上。
弘志一直想做一名建筑师:“是建造大楼的那种建筑师。不是软件架构师。就是实际的建筑设计。”他对计算机不感兴趣,直到大学的第一次(也是唯一一次)学期才接触编程。学校并不适合他,他回到了日本家乡。但他已经迷上了软件开发。在家时,他自学了编程,并开始接一些咨询工作。他还做了一些业余项目,包括为 Be 操作系统开发了一个文本引擎^(1),并将其开源。这项工作引起了 Be 公司员工的注意,弘志最终在那里找到了工作,并于 1996 年 12 月搬到了加利福尼亚。
弘志在苹果差点收购 Be 公司以提供下一个 MacOS 版本的一次事件后加入了 Be。但最终苹果收购了 NeXT 计算机。弘志回忆道:“我们是那家没有被收购的公司。”
三年后,弘志准备寻找新的机会。Be 公司时的同事 Steve Horowitz 将弘志介绍给了 Andy Rubin,弘志随后加入了 Danger。“我成了 Danger Research 的第一位员工。那时有三位创始人,而我是他们雇佣的第一个小角色。”
弘志将其他 Be(以及未来 Android)工程师带入了 Danger:Brian Swetland 和 Ficus Kirkpatrick。但弘志自己在那里的时间并不长,仅待了八个月就离开了。
在离开 Danger 后,弘志曾短暂地在 Palm 工作,而这家公司也是很多 Be 工程师在 Palm 收购 Be 后加入的公司。离开 Palm 后,他管理了 Good Technology 的一支工程团队(该公司当时正在开发移动通信软件),然后在 2005 年初再次加入了 Steve Horowitz。Steve 当时领导着微软的 IPTV 团队。
到了 2005 年底,弘志再次准备迎接新的挑战。“我当时正在日本度假,Andy 突然给我发了封电子邮件。自从我离开 Danger 后就没再和他联系过。他写道,‘嘿,我现在在 Google 做一些你可能会喜欢的事情。’他知道我喜欢无线设备,‘我觉得你应该来跟我们聊聊。’”
“当时我在微软工作,负责机顶盒的开发。这不是我想要的工作,我真的很怀念做移动设备的感觉。所以我在一月时给他打了电话。”
谷歌的面试和招聘过程从来都不以迅速或简单著称,但浩史的情况尤其独特。
尽管浩史在相关科技公司有着丰富的经验和悠久的工作记录,但他并不是谷歌面试的必胜之选,特别是因为他没有大学学位。Steve Horowitz 说:“当时的谷歌非常看重学历。谷歌那时的态度是,‘他没有学位,我不确定我们能否雇用他。’他们当时给出了很大的反抗。”
浩史说:“经过二十多次面试,因为他们无法搞清楚如何雇用我。他们让我写一篇文章。字面上说。我不知道他们是否完全理解^(2)这其中的讽刺。他们给我布置了作业,要我写一篇关于为什么我没完成大学学业的文章。”
“我差点说‘算了’。”
最终,团队成功说服了谷歌招聘委员会聘用浩史。然而,即使有了这一协议,加上超过 20 次面试的结果,以及那篇必定出色的“为什么我辍学”的文章,招聘委员会仍然拒绝聘用浩史为工程师。浩史说:“他们在某种程度上把我归为‘杂项’,并决定给我一个‘技术项目经理’的职位。”
在 1.0 版本的过程中,浩史参与了与合作伙伴公司的初步会议,并与他们合作确保事情的顺利进行。“这是技术和商业的结合,或者说是从不同角度来看,既是技术层面,也可能是商业层面。我们构建软件,但没有合作伙伴,没有来自其他公司的硬件,尤其是在当时我们没有 Nexus 或 Pixel...那时一切都依赖于 OEM 合作伙伴和运营商,这些公司将负责发布这些产品。我的工作就是负责项目管理。”
Brian Swetland 评论浩史在管理合作伙伴方面的角色:“没有人像他那样与合作伙伴打交道,部分原因是 a) 他非常专注,b) 他技术非常强。所以他总是能够理解潜在的技术问题,这在我们尝试从合作伙伴那里提取所需信息,或者让他们做一些需要解释的事情时,非常有帮助。”
浩史与系统团队紧密合作,因为那是安卓软件与合作伙伴硬件对接的地方。“Swetland 和我会一起去台北。他会在那里待三周。我去一周,然后他会独自待剩下的时间。确保启动顺利进行。启动内核,启动外围设备——他会与他们的工程师一起做这些,硬件和软件。然后原型机会送到这里,高层人员会在上面运行他们的东西。”
1.0 版本发布的同时,Steve Horowitz 离开了谷歌。Andy 仍然负责安卓,但当时有人来做工程总监的角色与 Steve 的合作非常顺利,于是浩史接任了这个角色。Tracey Cole 说:“Andy 非常依赖浩史,让他管理团队。他不喜欢管理人,他让浩史接手了这个工作。”
黄伟把 Android 的工程文化归功于广濑浩:“广濑愿意和我一起深入细节,了解事情是如何运作的。即便他后来成为了副总裁,仍然在负责 Android,他依然会联系我们,搞清楚‘嘿,短信不行了,Hangouts 坏了’。我认为他能够与团队其他成员建立联系,而不仅仅是与直接向他汇报的人员沟通。而且,他关心产品,这一点显而易见。我也很喜欢他作为我们和安迪之间的桥梁。”
“我不知道他是怎么做到的。你怎么才能做到既真诚,又具备足够的技术知识去问出正确的问题?这就是为什么他能走到今天的原因。”
广濑继续管理工程团队,直到 Droid 发布之后,并建立了像 Bacon Sundays(3)这样的传统,在每次发布之前通过集体努力确保发布顺利进行。(4)

广濑浩在 44 号楼里他那狭小的办公室,2008 年 9 月(图片由布赖恩·斯威特兰提供)
史蒂夫·霍罗维茨与工程学
如果你回顾我们所处的位置以及谁“懂得”移动技术,谁“不了解”,这一切都可以追溯到领导者们当时是否有信念或远见。
—史蒂夫·霍罗维茨
史蒂夫·霍罗维茨曾是 Android 团队的工程总监,直到 1.0 版本发布。他在 2006 年 2 月加入 Android 团队,那个时候团队刚开始扩张。当他加入时,团队大约有 20 名工程师,到了他们发布 1.0 版本时,团队成员几乎增加到了 100 人,历时将近三年。
史蒂夫·霍罗维茨在小学时学习了 BASIC 和汇编语言,使用的是 Apple II。到了高中,他将时间分配在科技新闻和编程之间。高中毕业后,他直接进入苹果公司实习,并且之后每年暑假都在苹果工作,直到大学毕业。毕业后,他全职加入苹果,参与了开发下一代 MacOS 的项目 Pink,以及开发下一代硬件的项目 Jaguar。
在苹果待了两年后,史蒂夫去了 Be 公司,在那里他为 BeOS 开发了 UI 工具包功能,比如 Tracker(相当于 Mac 上的 Finder)。在 Be 公司待了几年后,史蒂夫转到微软,加入了刚被微软收购的 WebTV 部门。在那里,他与未来的 Android 团队成员,如迈克·克莱伦、安迪·鲁宾和黄伟等人一起工作。他还最终聘请了广濑浩来负责微软 IPTV 平台的系统软件组。在微软期间,史蒂夫逐渐转向管理职务,这也为他日后在 Android 的角色奠定了基础。
在微软工作期间,史蒂夫收到了苹果公司 Tony Fadell^(6)的一个有趣邀请,要求他负责 iPod 的系统软件团队,而那时该团队正开始考虑 iPhone 的开发。“这是一个不错的提议。但我持有很多微软股票,而他们给我的只是一些苹果股票。那时,我喜欢我在微软做的工作。苹果的提议看起来很有趣,但苹果的[股票]必须上涨一百倍,才能接近微软的价值。当然,正如预料的那样,它们确实涨了——超过了一百倍。”
“Tony 的团队中的一些成员,以及另一个人 Scott Forstall,正在争夺 iPhone 操作系统架构的主导权。最终,我认为 Forstall 的版本赢了,但 Tony 团队的人加入了这个项目,成为其中的一部分。所以,在某种奇怪的平行宇宙中,我本可以在 iOS 上工作,而不是 Android。”
在史蒂夫在微软工作的这些年里,Andy Rubin 曾试图邀请他加入 Danger 公司,但史蒂夫并不相信他们具备成功的条件,所以他留在了微软。
然后在 2005 年秋季,也就是 Android 被 Google 收购几个月后,Andy 再次尝试。“他说,‘我希望你能过来负责 Android 的工程工作——我们刚刚被 Google 收购了。’当我和他交谈并意识到是 Google 将尝试这个项目时,我觉得现在所有的要素都具备了,能够真正颠覆移动行业。我告诉 Andy,我会加入。”
史蒂夫在 2006 年 2 月加入 Android,担任 Android 工程总监。
史蒂夫在 Android 的工作之一是招募人才。他几乎立即就把他的微软团队成员 Mike Cleron 引入了 Android 团队。
团队中的工程师们记得史蒂夫强大的管理技能,他让团队保持冷静,并严格裁剪功能,以便他们能够按计划发布 1.0 版本。史蒂夫的首要任务始终是确保产品能够按时发布。
Michael Morrissey 还记得史蒂夫处理 Google 事务的高效:“史蒂夫真的非常擅长管理 Google 的官僚体系。他知道如何绕过那些对 Android 不利的流程和程序。”
经理的职责之一是帮助团队成员的职业发展。但那时职业发展并不是迫切的问题;1.0 版本发布后才有时间讨论这个问题。那时工作是最重要的。Romain 记得在那个紧张的阶段,史蒂夫经常在周末给他发 IM 消息,通常是一句:“yt?”,^(7)接着就是关于需要修复的 bug 的讨论。
移动世界大会
史蒂夫是 Android 团队的领导层成员,因此他既负责工程管理,也协助商业方面的工作。“在我刚加入后,Andy、Rich Miner 和我一起去了 MWC^(8),带着 Android 的这个想法。那时基本上只是一个 Flash 演示,实际上并没有太多内容。”
“我们一直在尽可能多地与人会面,并向他们推销安卓的理念。我们有一个小房间,专门用来接待这些人。大部分人都对我们嗤之以鼻:‘等你们长大了再回来吧。’但我们和保罗·雅各布斯与桑贾伊·贾(高通高管)开了会,他们对此感到兴奋。他们很热情,想要探索更多。其他人则不屑一顾。”
“如果你回顾我们的历史,看看是谁‘理解’了移动领域,谁在移动领域成功,谁又没有成功,这一切都归结于领导者们是否在当时拥有信念或远见。”
“关于 MWC,有趣的是对比。如果你回顾当时的情况,它不过是我们在推销的这个理念,而现在,情况完全不同——现在它几乎是全部安卓。” 也就是说,安卓从当时在 MWC 上难以引起任何关注,到如今安卓在展会上占据如此重要的位置。
管理冲突
史蒂夫的一项重要工作就是调解各子团队之间的差异。来自 Danger 的工程师与来自 Be/PalmSource 和 WebTV/Microsoft 的工程师之间有着非常强烈的分歧。
“这就是安卓的特点——就像任何团队一样,它是由各种个性拼凑而成的。这个教训对任何人来说都是:小团队中的顶尖人才,最终会战胜大团队。这是毫无疑问的。而这正是我们在安卓中所拥有的。但是,正是这些才华和能量带来了冲突的机会,无论是在个人之间,还是在架构上。这就是我帮助引导的方向。”
离开安卓
1.0 版本发布后不久,史蒂夫离开了安卓(和谷歌)。他希望能担任更大的职位,做更多的不仅仅是工程管理的工作。离开之后,广志接管了团队。总有一种好奇,当我们在职业或生活中选择某条道路时:如果我们选择了另一条路会怎样?史蒂夫反思道:“有一个有趣的问题,没有人能够真正回答,包括我自己:如果我当时知道安卓会发展成今天这个样子,我会做出相同的决定吗?老实说,我不知道。”^(9)
瑞安·PC·吉布森得到了应有的回报
当时安卓还处于“雷达下”,但我听到了低语声。那是令人兴奋的低语声。
—瑞安·PC·吉布森
项目越大,团队越庞大,确保事情按计划进行,或者按特定的时间表完成就越困难。每个人都有责任确保这一点,但正是谷歌所称的技术项目经理(TPM)具有将细节落实的特别技能。广志(Hiroshi)在合作伙伴方面做这项工作,而瑞安·PC·吉布森(Ryan PC Gibson)则负责平台方面的工作。
瑞安接触编程的契机来自于看着母亲认真地将 BASIC 程序从杂志上抄写到他们的 Atari 800XL 上。“我学到编程大多数时候就是打字。直到今天,我还是不明白为什么软件开发需要这么长时间。”
Ryan 在 2005 年 7 月加入了 Google。他到达的那个月,Android 刚刚被收购,但他在 Google 的其他部门工作,参与一个内部销售工具的软件项目。他一直对移动技术很感兴趣,所以开始四处寻找是否有更符合自己兴趣的项目。“当时 Android 还处于‘低调阶段’,但我听到了些许风声,挺酷的风声。”
他认识了 Andy 和 Hiroshi,并与 Mike Cleron 进行了面试。“他给我展示了 Sooner,它有一个键盘和小的 D-pad。与那些老款诺基亚手机相比,它非常棒,尽管在 2D 应用矩阵中导航感觉有些笨拙。触摸屏就在眼前,改变了一切。我在 2007 年 1 月加入了[Android 团队],感觉就像回到我以前的创业公司(只是这次有了更好的食物和更稳固的财务状况)。”
那时作为 TPM(技术项目经理)是非常具有挑战性的,因为许多团队对这个角色并不熟悉,Ryan 自己也是如此。“我大部分职业生涯都是软件开发人员,但逐渐开始转向管理。我以前从未正式做过项目管理或程序管理,所以我必须边走边学。更具挑战性的是,当时 Google 的 TPM 非常少,而且大多数 Google 员工从未在他们的团队中拥有 TPM。”
幸运的是,Android 为良好的项目管理提供了充足的机会,早期团队也认识到了这一点的好处。“Hiroshi、Mike Cleron、Dianne 和 Brian Swetland 都曾在过去的公司中与项目经理有过良好的合作经验。他们理解项目经理在成功发布产品中的价值。我们仍然有点麻烦,但都是以有益的方式。其次,Android 项目的性质使得专门的项目管理成为可能,满足了三个重要标准:1)有大量多样化的贡献者——Android 开发人员、Google 应用开发人员、开源开发人员;2)有大量多样化的利益相关者——OEM 厂商、运营商、SOC 供应商;3)电子产品销售周期的紧迫时间表。所以 Android 是一个非常适合做项目经理的地方。”
问题非常巨大:如何尽快创建、巩固并发布一个完整的操作系统、应用程序和设备。同时,团队仍在组建当中,平台的许多基本组成部分甚至还没有确定,更不用说编写了。但他们仍然需要提出一个现实的时间表并开始执行。而且他们需要产品尽早推出,以确保它能够真正产生影响。“项目管理在其中扮演了非常重要的角色。我们落后了一年,如果拖延到下一年,可能就会变成历史的脚注,而不是一个可行的替代方案。但我们不能随便发布任何东西——它必须是扎实的。”
“第一天,Hiroshi 递给我一张电子版的甘特图,列出了数百个任务,日期远远超出了我们的交付日期。他附带了一句‘啊,救命!’我想。在回顾时,这确实是一个典型的项目管理挑战,但对我来说一切都是新的。我和当时大约 30 个开发人员进行了交流。作为一个具有初创公司背景的开发人员,这确实帮了我很多。”
“我一开始帮助软件工程师们将他们的工作组织成一系列的里程碑,直到 1.0 发布。那是一个疯狂的时期,因为我们需要在商业和产品计划仍未明确的情况下,搞清楚如何稳定代码基础。在那些早期,我对敏捷开发^(10)感到非常兴奋,但安卓内部却存在深深的怀疑。其他公司在实施敏捷方法时的一些失败经验,令很多领导层产生了抵触情绪。但随着产品定义的不断发展,项目实际上非常适合进行时间框架开发。没人知道我们什么时候能完成,因为当时还不清楚‘完成’到底是什么意思。”
“我制定了几个初步的里程碑,‘m1’、‘m2’等,并将问题倒过来问:‘我们在每个里程碑之前能完成什么?’我小心翼翼地询问开发人员关于‘理想工程日’(IEDs)的粗略估算,但尽量避免使用传统的敏捷术语。IEDs 在最初的几个里程碑中大致有效,我们弄清楚了如何逐步减少特性工作,并朝着一些目标取得进展。最大的收获是将特性工作追踪从甘特图转移到之前已经用于追踪 Bug 工作的地方。多年来,我们逐渐不再使用 IEDs 来估算,但发布过程中的很多节奏——比如零缺陷跳跃^(11)、特性完成等——依然保留了下来。随着我们从错误中吸取教训,发布流程得到了极大的改善,并且逐步变得更加庞大和复杂。”
甜点时光
安卓系统使用甜点名称来命名发布版本的传统,源自于 Ryan 的项目管理技巧。“我记得很多关于‘1.0’意味着什么的早期辩论。Dianne、Swetland 和其他人对这个定义非常有热情。为了推进讨论,我建议我们使用代号,并稍后再确定哪个代号会是 1.0。Dianne 同意了,但条件是这些代号要按字母顺序排列,因此‘Astro Boy’(12)和‘Bender’(13)显然会成为我们的第一个安卓代号!我们计划将‘C3PO’作为第三个,而这看起来最终会是 1.0……但这后来成了一个问题(14)。处理许可问题会拖慢我们的进度,我们意识到未来很多版本也可能遇到这种情况。我们需要找到其他办法,而我(现在仍然)对杯子蛋糕着迷。我也很喜欢这个想法:我们可以用‘Sprinkles’(15)来庆祝我们的发布,因此甜点的概念就这样真正地启动了!”
Michael Morrissey 记得 Ryan 对发布的贡献,“通过不断的软性推动,Ryan 理解足够的技术层面,但始终专注于推动进度。”
Peisun Wu 与项目管理
Ryan 的同事之一,是 Hiroshi TPM 团队的成员 Peisun Wu,她于 2007 年 9 月加入。尽管她当时已经在谷歌担任工程经理,但她作为 TPM 加入 Android 团队,因为她之前做过这份工作,而那时 Android 团队正需要这种角色,尤其是在向 1.0 版本发布过渡时。
Peisun 接触计算机编程的方式和许多工程师一样:视频游戏。当她读三年级时,她的父母决定她玩得够多了,不再为她买游戏。“天哪,”她想,“如果我不能买游戏,或许我可以试着弄明白如何制作自己的游戏。”接下来的一年,她大部分时间都在图书馆,阅读编程书籍并在图书馆的电脑上进行实验,直到她通过做家务赚够了钱,买了一台属于自己的电脑。
几年后,凭借认知科学学位,她在几家初创公司工作,处理如何管理非结构化数据的问题。这些公司中的第二家,Applied Semantics,在 2003 年被谷歌收购,收购是为了其广告技术,这项技术最终成为了谷歌的 AdSense 产品。
在谷歌,Peisun 曾参与搜索设备的工作^16,然后是 Google Checkout,最终在 2007 年加入了 Android 团队,恰好是在公开 SDK 首次发布的时候。
Peisun 在 Android 工作期间与多个不同小组合作,最初是与媒体团队合作。她负责管理与外部公司及其技术的关系,包括 PacketVideo(为 Android 的视频功能提供软件)和 Esmertec。
Esmertec 提供了 Android 设备随附的媒体应用程序,包括一个音乐应用和一个即时消息(IM)客户端。要让这个应用程序与 Android 上的基础消息平台以及 UI 设计的晚期变更正常工作,需要处理很多细节,Peisun 加入了团队,前往北京和苏黎世,与位于中国成都的 Esmertec 工程团队一起合作,确保这些细节得到妥善处理。
在她一次前往苏黎世的旅行中,她注意到一位 Esmertec 的工程师带了一个行李箱,里面全是辣酱。四川省的成都以辛辣食物闻名,而苏黎世则……并非如此。这个装满辣椒的行李箱被视为在那两周里在苏黎世生活的一项重要应急措施。
除了在媒体和信息传递方面的工作,佩孙还帮助丹·博尔斯坦(Dan Borstein)制定了 Dalvik 的发布计划,协助获取设备的早期字体,并在硬件团队进行设备 FCC 认证测试时提供帮助。团队当时进行这种多项目工作的情况并不罕见:“那时并不像现在这样‘某人属于某个团队’,而是任何需要帮助的地方都会有人参与。只要有空的人,就会跳进去帮忙。”
第二十八章:交易
合作伙伴关系对 Android 至关重要,至今仍然如此。Android 增长的关键之一是,它不仅仅是谷歌在发布 Android 手机,而是所有人都在参与。^(1)
在早期,有几个人在处理不同方面的合作伙伴关系和商业交易。Andy Rubin 对与谁合作以及如何使这项战略成功有很多想法。毕竟,他共同创办并运营过一家成功的移动设备公司(Danger)。但还有 Android 的联合创始人 Nick Sears,曾任职 T-Mobile,他在将 T-Mobile 签约为 G1 的 Android 首发合作伙伴方面发挥了重要作用。Hiroshi Lockheimer 在合作伙伴关系方面也至关重要,他负责管理 Android 在合作伙伴设备上的开发。另一个 Android 的联合创始人 Rich Miner 曾在 Orange Telecom 工作,与运营商合作,并管理过一个投资于移动和平台公司的风险投资基金(包括 Danger)。除了管理负责 Android 浏览器和语音识别的工程团队外,Rich 还是商业团队的一员,帮助达成了摩托罗拉 Droid 的交易,与 Hiroshi 和 Tom Moss 一起。
Tom Moss 与商业交易
Tom Moss 参与了早期 Android 中的许多关键商业交易,但他当时并没有从事商业方面的工作。“我最初是以律师身份加入 Android 的。我是最糟糕的那种人。我们摧毁了一切。”
Tom 于 2007 年 5 月加入谷歌的法律部门。在加入谷歌之前,他的专长之一是开源技术。一开始,他就被告知将参与一个名为 Android 的开源项目,该项目将在那个秋季发布 SDK。
“我做的第一笔交易之一是与高通合作,获取 7200 AMSS 芯片组代码的许可,开发 Linux 驱动程序,以便发布。这当时非常复杂,因为高通对开源极为恐惧。”
Tom 最初从法律角度提供支持,但最终直接参与交易。“我开始作为律师支持 Andy 进行交易,还有 Rich Miner 和其他一些人。越来越多的时候,Andy 会直接把我丢下:‘这是我们需要的交易,去做吧。’Andy 很忙,他不愿意坐下来参与所有的谈判和一切事务。”
他还负责制定如何连接所有不同利益相关者的战略:应用开发者、手机制造商、运营商和平台软件团队。开源软件的一大难题是激励机制;除了谷歌,为什么这些合作伙伴会关心 Android 平台?“如何以一种能保持兼容性的方式,激励每个人投入到这个生态系统中?”
当然,应用开发者会非常关注兼容性。在不同版本的 Android 上运行相同的应用程序,比起开发者在 Symbian 和 Java ME 等平台上遇到的情况要好得多,在那些平台上,应用程序通常需要重写才能适配不同的设备。但对于制造商来说,情况不同,他们习惯于只对自己的设备和实现负责的世界。
幸运的是,谷歌拥有一些制造商希望在其设备上使用的热门应用程序,包括 Maps、YouTube 和网页浏览器。因此,Tom 制定了一个系统,通过提供这些应用程序的访问权限,作为合作伙伴保持兼容性的激励,要求他们按原样发布 Android,而不是发布修改版的 Android^(2)。
在不同的地方工作
由于 Tom 的工作更多是关于达成交易而非法律事务,他加入了一个叫做新业务发展(NBD)的团队,这个团队专门帮助谷歌的各个团队处理业务方面的事务。他继续专注于 Android,但仍然没有直接向 Android 团队汇报。
与此同时,Andy 需要在日本组建一个团队来帮助解决那里的开发问题(包括国际化和键盘支持)。Tom 自愿提供帮助。这个决定对他来说是合情合理的,因为他参与的很多交易都在亚洲地区。他转到谷歌东京办公室,并组建了一支工程师团队,错过了他搬到东京后仅两周在加利福尼亚举行的 G1 发布会。
与此同时,Andy 希望能更直接地了解 Tom 在 Android 工作的情况,于是 Tom 转到了 Android 团队。这意味着由于与 Android 是大公司一部分的“愚蠢”原因,Tom 必须被重新归类为工程师。“我相信我是谷歌第一个从业务部门转到工程岗位的人^(3)。所以从名义上讲,我是工程师。需要明确的是,我从未写过代码。”
发布合作伙伴设备
与此同时,Tom 在东京办公室忙着帮助该地区的合作伙伴。“我负责了日本市场。我们还推出了澳大利亚,应该还有新加坡。”
“那时,谷歌的角色很有意思。发布一款手机,仅仅是运营商从 OEM(原始设备制造商)购买手机。但我们在许多交易中都起到了关键作用,不论是把我们的品牌或营销放在包装盒上,还是直接放在手机上,或者只是放在营销活动中。我们通过这些交易为 Android 创造了势头。我们会与运营商谈判,也会与手机制造商谈判。”
“我举个例子。我会去谈判协议,以确保手机上有正确的内容,正确的应用或服务,和运营商 Docomo 谈判,与 HTC 谈判。然后我们与他们一起做市场推广活动。Monma-san [Tom 团队的一名工程师]和我校对了用户手册的日英翻译,并做了评论,修正了他们的一些非常愚蠢的错误,比如‘电池是消耗品’,就像电池可以吃一样。我们做了所有的事情。我们做了推出产品所需的每一部分。”
Jeff Hamilton 指出,这种全球合作伙伴关系的方式是 Android 能够达到目前规模的原因。“外面有大约二十亿^(4)部设备。一个公司无法制造那么多设备并支持它们。尤其是设备的种类:人们想要的不同设备、不同的价格点、配置,所有这些都涉及。这是一个巨大的种类。通过做开源的事情,拥有一个支持这些的技术栈,并让合作伙伴建立生产这些所需设备的工厂——比如土耳其的网络要求,或者其他的不同需求——一个公司是无法承担所有这些的。不同地区有不同的要求。我们通过让不同的公司承担这些工作来实现了扩展。”
第二十九章:产品 vs. 平台
这就是为什么它叫 ANDroid 而不是 ORdroid。因为如果我们在两种选择之间做决定,我们总是两者都选。
—团队格言(匿名)
在早期以及以后的多年时间里,团队内部一直在进行一个持续的辩论:他们是在建造一个产品还是一个平台?也就是说,他们是在尝试建造一个或多个手机(产品),还是一个可以跨多个制造商的多种手机使用的操作系统,现在和将来(一个平台)?
现在显然很清楚,特别是考虑到 Android 生态系统的广泛覆盖,Android 是一个平台。是的,它在谷歌的手机上运行,包括 Nexus 系列和更近期的 Pixel 手机。它也在全球许多其他手机上运行,其中大多数从未被 Android 团队中的任何人看到过,但所有这些设备都作为 Android 生态系统的一部分运行 Google 应用和 Google Play 商店。但当时,人们并不清楚应该优先考虑什么。由于 1.0 版本明显针对 G1 手机,两者之间的区别变得模糊起来。更加复杂化的辩论是,构建一个特定的产品总是比为长远打造更灵活的平台更容易(也更快)。因此,如果 Android 的主要优先事项仅仅是推出市场上的某些东西,专注于产品是正确的选择。
与此同时,iPhone 采取了非常注重产品的方法。正如当时的 iPhone 产品营销高级总监 Bob Borchers 所说:“那时候,我们并没有把 iOS 视为一个平台。” 实际上,App Store 甚至不是那款首个设备的计划的一部分;iPhone 只是一个带有苹果应用的苹果设备。这种方法使得苹果能够专注于确保那款特定产品的每一个细节都准确无误。
从那时起,苹果推出了许多后续手机,并且现在拥有了 App Store 和庞大的开发者生态系统。但他们始终清楚自己在为哪些产品而建造,并可以调整他们所发布的操作系统和平台。谷歌也推出了许多手机……但与其他制造商出货量和种类的设备相比,这个数字微不足道。因此,对 Android 来说,更重要的是能够适配所有这些设备,而不是在谷歌设备上完美运行,但难以处理 OEMs。
在团队内部,关于产品与平台的辩论可以由人们来自的不同公司来代表:Danger、Be/PalmSource 和 WebTV/Microsoft。来自 Danger 的人更喜欢简单的解决方案,这使他们更加关注产品。而来自 Be/PalmSource 和 WebTV/Microsoft 的人则更倾向于平台思维,并支持 Android 采取这种方式。
Romain Guy 说:“来自 Palm 的人曾经参与过 Palm OS 6 的开发,支持 Palm OS 5 的兼容性。他们亲眼见证了一个不具备未来构建的操作系统会发生什么,它没有任何分辨率、GPU 等概念。”
布莱恩·斯威特兰德看到过两种观点,因为他曾在 Be 和 Danger 工作过。“你需要两者。这个是我从 Be 学到的教训。Be 有时会陷入死胡同——过于专注于成为平台。如果你不做真正的应用,只是构建一个纯粹的平台,那么你就无法闭合这个循环。你没有做出人们需要的东西。”
布莱恩说,Android 团队的辩论至今仍在继续。“我认为到现在也从未变得明确过。这曾经让安迪十分头疼。我们会召开全员会议,我或戴夫·博特会问我们到底在做什么。我们显然是在构建一个平台,而平台中有产品。但我们是在构建‘谷歌手机’,一个垂直的东西,我们的产品吗?还是我们在构建一个期待 OEM 厂商基于这个平台推出自己品牌的手机?或者是介于两者之间的某种东西?多年来,我们做了所有这些事情。”
“Nexus 设备,现在的 Pixel 设备,感觉更具垂直性。但也有这样一个广泛的生态系统,人们做着各种疯狂的事情。然后你有像亚马逊和 Fire 那样的产品,他们把平台作为起点,构建出自己的平台,这个平台从原始平台派生,但并不完全相同。”
麦克·克莱隆说,戴安娜“拥有最清晰的远见,‘这不仅仅是发布 G1,活下来再说。’她在为那些即将到来的事情铺设基础,至少对我来说,可能对大多数人来说都是如此。2006-2007 年,戴安娜看到了我们直到 2013 年才需要的东西,她不知怎么地把这些东西融入了 Android 的一些基础概念中。”
这场辩论也发生在谷歌的董事会会议室里。那时的高管评审显示,谷歌的高层执行人员意见不一:有些人优先考虑 Android 打造手机,有些人偏向平台化路线,还有一些人站在中间立场。
戴安娜总结了这场辩论:“平台还是产品:这一直是 Danger 和 Palm OS 团队之间的争论。安迪的答案当然是‘两者都要。’这才是正确的答案。”
第三十章:Android != Google^(1)
在早期的那些年里,没人怀疑过其他人是否真正投入到了这个事业中。我们都在同一辆列车上。
—布莱恩·琼斯
从一开始,Android 就拥有一种与 Google 其他部门截然不同的文化。尽管这个小型的 Android 初创公司被吸收入了更大的 Google 公司,Andy 还是尽力保持团队的独立性。
杰森·帕克斯说:“Andy 和领导团队意识到,为了成功,我们需要与更大的 Google 文化保持独立,创造我们自己的文化来实现这个目标。我不知道他是怎么说服埃里克、拉里和谢尔盖的,但他做到了。我们被孤立起来,像一个小型初创公司一样运营,资金来自 Google。”
迈克·克莱伦说,Andy 故意让团队与公司其他部门保持独立,“给了团队喘息的空间,不必不断向大 G Google 汇报工作。”
不是团队中的每个人都同意这种做法。迈克·弗莱明说:“Android 与 Google 是隔离的。这真的是一个自上而下的决策。我记得我当时觉得这不是个好主意,并且反对这个主意。我真的希望我们能够连接起来,建立桥梁,参与 Google 文化。但这根本没有发生。”
Android 的独立性在很多方面得以体现,包括将项目保密,并且不参与更大的讨论和公司会议,团队认为这些会让进展变慢。
所有这些动态都有助于保持团队专注于一个目标——发布每个版本。但就像澳大利亚与其他大洲的物理隔离导致了奇异的亚种一样,Android 发展出了与其更大、更稳重的企业母公司不同的文化,甚至有点更加鲁莽。
布莱恩·琼斯评论了 Android 文化以及它赋予团队的独特使命感。“我们是在 Google 内部的一个小型初创公司。我们被保护在大公司的外面。我们是一个小小的飞地,拥有很大的自治权。一旦你加入了,大家都知道你是为了这个使命而努力。”
“我们可以就某个实现细节,或者需要采取什么技术方法来实现目标进行热烈而充满激情的争论。但在那些早期的岁月里,没人怀疑过其他人是否真正投入到了这个事业中。我们都在同一辆列车上。”
Web 与移动
使 Android 与 Google 其他部门保持独立的原因之一,是因为它是一个与 Google 其他产品截然不同的产品。当时的 Google 主要开发 Web 应用程序。这导致了两个重要的后果:一是 Google 内部不满 Android 不是基于 Web 的,二是无法理解移动软件的时间框架现实。
首先,安卓所做的事情曾经遭到核心的不信任,因为谷歌本质上是一个专注于网络技术的公司。那时通过网络可以做很多事情;为什么安卓不是基于网络技术呢?当时其他移动平台(包括 Palm 的 WebOS,甚至 iPhone,苹果最初对外开发者的计划是基于网络应用)的确是使用了网络技术,这进一步支持了这一论点。然而,安卓固执地拒绝走这条路^(2)。它提供了在原生应用中集成网页内容的能力(通过 WebView,并提供了完整的浏览器应用),但应用程序的开发仍然要求使用原生(而非网络)技术,包括不同的编程语言、不同的 API,以及与网页应用截然不同的整体开发方法。
其次,安卓试图推出一种与谷歌习惯写作的网络应用产品完全不同的产品。如果你想发布一个新的搜索版本,你可以今天下午就完成。如果那个版本有 bug,你可以修复它并在今晚更新应用。网络产品通常每几周就会有一次常规发布,团队会不断进行发布和迭代。但是安卓有着非常不同的限制条件,这使得这种方法和思维方式在安卓中无法实施。
布赖恩·琼斯解释道:“在安卓中,有硬件组件、制造组件、运营商组件,还有合作伙伴关系。你可以发布和迭代搜索算法,但你不能发布和迭代硬件。你必须设定一个日期并从后往前倒推。”
布赖恩·斯威特兰德表示同意:“现实情况是,当你试图发布消费电子产品时,假如有人正在投入生产线,或者正在准备一个大规模的营销活动以实现销售目标,你不能错过,否则你真的会给合作伙伴带来麻烦。当你试图赶上这些最后期限时,你会变得有些疯狂,因为如果你错过了这个窗口……你可能三个月后都无法发货。你甚至永远都可能无法发货,因为你现在必须重新构建一个完全不同的产品。”
斯威特兰德将这种方法与安卓之外的谷歌团队的做法进行了对比:“那都是网络相关的东西:你发布了它,如果它不起作用,你就回滚。但在工厂烧录镜像时,情况就没那么简单了。”^(3)
从谷歌其他部门转到安卓团队的陈秋基谈到了这种硬件驱动的动态:“安卓是第一个教会我圣诞节在十月就结束的团队。如果你希望你的设备在圣诞节上市,所有的工作必须在十月之前完成。那是一个疯狂的最后期限,因为电路板^(4)必须定稿。这是我第一次遇到不能错过的真正的最后期限。圣诞节不会等任何人,电路板的打印速度有限,因此你不能错过十月的最后期限。”
这种以日期为驱动的心态最终形成了那种在早期定义安卓的勤奋工作、以截止日期为驱动的文化。
第三十一章:西部荒野
Android 那时就像是西部荒野。
—Evan Millar
Android 也发展出了自己独特的工程文化,这源于其与 Google 其他部门的隔离,以及与公司其他产品相比,Android 所从事的产品有着根本性的不同。Evan Millar 曾观察到:“那时的 Android 很像西部荒野。那时几乎没有规则,也没有多少工具。没有什么最佳实践或风格指南,甚至没有任何人告诉你做事的正确方式。但有趣的是,这也意味着你几乎可以做任何你想做的事情,尝试任何你想尝试的东西。这是一个非常开放、鼓励创新和尝试的文化,我真的很喜欢。在 Android 工作时,我感到非常快乐,持续了很长时间。”
“回过头来看,我能看到这种方法的利与弊。显然,有很多人在之前做过类似的事情,知道自己在做什么。Android 上有很多聪明的人,经验丰富的人。这些人中的许多人曾在 Be 工作并推出了操作系统,有些人曾在 Apple 工作并参与了类似的项目。所以并不是我们没有深厚的专业知识和经验,因为我们确实有。但那时的感觉就像是西部荒野。感觉没有人真正知道自己在做什么,我们只是摸索着前进。我们不知道最终会失败,还是会成功。当它成功时,我想人们既惊讶又兴奋。”
Android 和 Google 的文化之间也存在着更微妙的差异。Google 长期以来一直有一个“20%时间”的概念,允许员工将最多 20%的时间用于一些可能对 Google 有益的项目。^(1) 这是一个伟大的传统,催生了一些出色的产品,包括 Gmail。而 Android 的工程师通常忙于本职工作,很少有时间去考虑还能做些什么,因此“20%时间”在 Android 团队中并不常见。
Android vs. Google
Adam Bliss 曾在第一个版本的 Maps 项目中工作,他曾表示自己喜欢为 Android 工作,但有时也会想念为 Google 工作的时光。
—Andy McFadden
在 Android 被收购后的头几年,Google 的许多人根本不知道 Android 的存在,因为这个项目非常保密。但当人们开始知道它时,Android 并没有被视为一个成功的项目。
Dan Egnor 于 2007 年 8 月加入 Android 的服务团队,之前他在 Google 的搜索团队工作,距离 SDK 发布还有两个月。“当我决定加入 Android 时,有些人就问:‘你为什么要做这个?iPhone 显然在主导市场,它是如此令人惊叹的产品,为什么要与它对抗呢?’在某些情况下,他们曾看到早期的原型,并且说:‘你们差不多落后几个月,为什么要去做这个?Apple 显然会赢。’”
San Mehat 也从 Google 的其他团队转到了 Android。“当我们收购 Android 时,大多数人都在想,‘我们到底在做什么?’”
当时,Dave Burke 正在领导伦敦的移动团队,负责开发非 Android 平台的 Google 应用。他记得当时人们对 Android 的内部看法:“这只是一个随机的副项目。根本不可能成功。人们不会那么消极,但他们会说,‘这太疯狂了。你怎么可能影响电信行业呢?’”
与此同时,Android 团队为了赶上 1.0 的发布,忙得不可开交,他们没有太多时间与 Google 其他团队合作。Tom Moss 记得,“我们烧断了很多桥梁。但我们也不得不这么做。我们确实必须说,‘不,我们有一个使命,我们必须坚持这个使命。当我们成功时,一切都会变得更容易。’”
Bob Lee 是从 Google 其他部门转到 Android 团队的人员之一,“这就像是在公司内部的一个公司。一些人对于被收购感到有些怨恨,想要保持那种拼搏的精神。一开始,我们没有代码审查,面试过程也不同,人们不写测试……对我来说,这有点像文化冲击。”
也来自 Google 其他团队的 Peisun Wu 同意这一点。她觉得这让她想起了她在 Google 之前曾工作过的公司。“典型的产品经理角色:设计文档、代码审查等,在我加入 Android 后完全被抛到了一边。对我来说并不那么震惊,因为我曾在两家创业公司工作过,所以这对我来说是正常的。感觉就像是又回到了一个创业公司。它完全不像 Google。对那些从 Google 来的人来说,这简直是一个粗暴的觉醒。”
Ficus Kirkpatrick 说,“从另一方看,他们把我们当作小丑。我们没有做现代化的测试软件实践——我们根本没做任何测试……这基本上是事实。它变得根深蒂固,几乎成了宗教。”
从 Google 的移动团队转到 Android 的 Cédric Beust 说:“我有一种明确的感觉,当我加入 Android 时,我不再是 Google 的一部分。我进入了一个黑洞。”
Evan Millar 于 2012 年从 Android 转到 Google 内部的另一个团队。他记得,“在很多方面,这就像是加入了另一家公司。”
第三十二章:硬件的乐趣
由于那时每个人都花费大量时间在办公室,偶尔会有人尝试修改和个性化工作环境。
禁止枪支
罗曼·盖谈到了他尝试通过强硬手段来阻止干扰。
“我们都很努力工作,很多人总是要求我们[框架团队]做很多事情。不知道为什么,我下单买了一把泡泡枪,因为显然这是美国公司开放空间里的常见做法。”
“它被挂在我的办公室天花板上,所以当你打开门时,枪口正对着门。上面有一张纸条,写着‘禁止’。”
“有一天我在家工作,第二天回来后发现我的泡泡枪被安装在了三脚架上,电动机加速了。”
“安迪看到了那把枪,虽然我不在现场,但他把它安装在三脚架上,还加了电动机。桌上有一个轨迹球,可以旋转三脚架上的枪支,并且比正常情况下更快地发射,因为他用了一个更强力的电动机。”
风雨中的任何港口
有一天,丹·莫里尔注意到墙中间插座板上有一个可疑的 USB 端口,除了它那神秘的标签外,完全没有任何提示说明它的用途。

建筑 44 墙中间的一个神秘 USB 端口(图片由乔·奥诺拉托提供)
丹提交了一个工作请求,要求网络基础设施团队调查此事,标题为“B44-2 墙上为什么会有一个 USB 端口?”
谷歌非常重视安全问题,包括物理安全和技术安全。一个裸露的、带有神秘标签的 USB 端口引发了担忧。工单被提交,安全人员被警告,并且展开了移除该端口的操作。
一支电气团队接管了这个插座另一边的房间,并在外面安置了守卫。电工们在面板后面切开了干墙,揭示了事情的真相。
墙面板背后是……什么都没有。它只是一个嵌入墙里的 USB 端口。原来是个恶作剧。或者,更准确地说,是一些工程师(特别是布莱恩·琼斯、乔·奥诺拉托和布鲁斯·盖)拥有了比计划更多的硬件。他们小心地在干墙上切了个洞,凭借热熔胶和灵感,将一个从旧工作站借来的 USB 端口插了进去。布鲁斯还添加了标签,试图让它看起来更正式。他们并没有更复杂的计划;他们只是觉得它放在那里什么都不做,挺有意思的。谷歌安全部门并不这么认为。
电工将现有的墙面板更换为一个空白面板,虽然提供了相同的功能,但空间更小,不容易搞恶作剧。
开关语句
USB 端口修复后留下的空白墙面板的诱惑太大了;它迫切需要一些东西来填补。团队不想再让谷歌安全部门感到紧张,但他们必须做些什么。
Android 部门里总是有各种杂乱的硬件,尤其是布莱恩·琼斯的桌子附近。所以乔和布莱恩翻找了周围的零件,最终做出了一个控制互联网的开关。
翻转开关^(1)导致灯变为绿色,并且开关开始振动(团队找到了某些触觉硬件,使得开关关闭时,面板会振动)。

绿色的灯表示互联网已开启。翻转开关会导致灯变红并且开关开始振动。(照片由杰里米·米洛提供。)
安全部门对这个没有问题;他们允许它在 Android 团队占据那栋楼的整个时间里保持原样。
互联网仍然正常工作,所以可以推测还没有人关掉它。
第三十三章:与机器人一起玩耍
安迪·鲁宾一直对机器人和各种机器有浓厚的兴趣。他在所有的项目中都延续了这一兴趣,包括在 2013 年离开安卓,转而在谷歌的一个不同部门从事机器人工作。
对机器人和各种小工具的偏爱在早期的安卓中以不同的方式表现出来。
安迪参与的一个机器人项目是咖啡师机器人;他造了一个机器人来制作拿铁艺术。尚不清楚它是否完全正常工作,但在 45 号楼的某个楼上的微型厨房里,确实有一台外形奇怪的机器。该区域被用绳索围了起来,以保护潜在客户^(1)。

你更喜欢脱脂牛奶还是全脂牛奶?安迪的咖啡师机器人制作了一杯拿铁。(图片提供:Daniel Switkin。)
机器人还装饰了安卓大楼的走廊。随着安卓的发展并扩展到其他大楼,它们分布在谷歌校园各地。

电影禁忌星球中的机器人罗比。罗比目前住在 43 号楼的二楼,该楼曾是安卓团队的办公楼。

来自太空失落的机器人,现栖息在谷歌 43 号楼大堂后方

这位威武的赛隆战士(来自太空堡垒卡拉狄加)在 44 号楼的框架团队区域守卫着。随着时间的推移,他积累了配件,如加拿大国旗披风、曲棍球棍和一顶 Noogler 帽子。(图片提供:Anand Agarawala。)
第三十四章:更努力工作,而不是更聪明工作
在安卓团队,投入大量工作时间在文化上非常有价值。
—Ficus Kirkpatrick
安卓团队在安卓内部,以及整个谷歌范围内,最为人知的特点就是非常非常努力地工作。Ficus Kirkpatrick 称其为“安卓的货币”。
“我不觉得自己是一个特别聪明的工程师,但我拼命工作。我会通过努力工作来弥补我教育背景的不足,并投入大量不健康的工作时间。在前四五年里,有一段时间几乎是我清醒时做的唯一事。而且我没有得到我应得的睡眠。我知道我不是唯一一个这样的人。”
“有一个月,我每天都在工作。我早上最晚是 9:30 到公司,最早离开的时间是凌晨 1:30。我记得凌晨 2:30 回到家时,我只想做点不是工作的事情,重新找回自己的生活。我躺在床上玩这款游戏,《游戏开发故事》。我几乎睁不开眼,但出于倔强,我就想着‘我要玩得开心!’然后我意识到,过去的 20 分钟,我其实是在模拟管理一个软件项目的过程。^(1)”
“大部分时间,超时工作是自愿的。我们真的很想做得尽可能多。我总是把它和耐力型运动项目进行比较;当时很痛苦,但结束时会觉得很高兴,你会和人们建立起联系。这有点像是一种低级的心理疾病,你总是一次又一次地自愿去体验。”
Rebecca Zavin 同意道:“那种与同伴们全力以赴一起工作并最终交付的满足感真的很有回报。那种‘我们要加班,把它完成,我们大家一起奋斗!’的专注。这就是创业公司的特点。”
Peisun Wu 指出,这种强度是自我驱动的。没有人强迫他们加班,或者因为按时下班而受到惩罚。“我们都留下来,因为我们想看到某些事情真正取得进展。”
Jason Parks:“我们工作了大量的时间。每周,唯一我老婆能见到我的时候,就是她来和我一起吃晚饭。我会很晚回家,睡几个小时后再回到办公室。她唯一能见到我的时候,就是来吃晚饭的时候。”
Fadden 回忆起 Brian Swetland 的努力和专注:“有一天,Andy Rubin 走进来说,‘嘿,Swetland,怎么样?’ Swetland 没有抬头,嘟囔了一句,类似于如果不被打扰,事情会进行得更顺利,然后继续打字。Andy 就站在那里。最后,Swetland 抬起头,发现 Larry Page 也站在那里。”
显然,大家长时间工作对团队产生了负面影响。例如,Tracey Cole 见证了这影响到她的招聘能力:“当我第一次尝试建立我的行政团队时,没有人(来自谷歌其他团队的人)愿意来这里,因为他们都听说我们工作太辛苦了。”
Tom Moss 谈到团队士气的影响:“在我离开时,我们的士气得分最低。但魔力就是发布。发布能解决一切问题。多少次 Swetland 和其他人都说,‘我真的要辞职了!’然后我们发布了,举办了派对,大家都感觉不错,又都愿意再继续做下去。”
“那段时间真棒。我喜欢那段经历。我们都喜欢。我们感觉自己就像海军陆战队的特种部队,正在做这个令人惊叹的项目。就是我们对抗全世界,凭着咬紧牙关和兄弟情谊走到最后。是的,我们都很沮丧,工作过度,没怎么睡觉。但尽管我们抱怨,尽管我们说‘士气低落’,员工流动率实际上是极低的。”
2010 年,Tom 离开了 Google,创办了一家公司。他离开时和 Andy 谈了话。
“我的女儿是在 G1 发布时出生的。等到我们发布 G1 时,她已经四个月大了。临走时,[Andy] 对我说,‘你怎么能在家里有个小孩的情况下做这个创业的事情?’
“我当时想,‘除非他们发明了每天第 25 个小时,否则我再也不能比过去四年来为你们工作得更辛苦了。’”
“那一刻你会想,‘你们真的意识到吗?’”
San Mehat 回忆起团队的努力:“我喜欢那个团队,他们真的是太棒了。我觉得我可能再也做不来了。再做一次可能会把我累死。”
最终,1.0 完成了。一片诡异的寂静降临。
Romain Guy 回忆起 1.0 发布前的那段时间。发布停止工作后的三周里,设备才会供人购买。“我们什么都做不了。我们不知道自己是否还在做生意。我记得有一天晚上 5 点,我在家里,这种情况以前从未发生过。我不知道该做什么。人们在家里都做些什么呢?”
然后 1.0 发布了,设备进入了商店,机器重新启动了。团队又回到了辛勤工作中,开始推出更多版本。因为有一个持续的压力:每个版本都必须按时交付以配合合作伙伴的硬件发布。此外,团队有一个共同的愿望,那就是让 Android 成功。虽然你可以眯着眼睛看到未来的影子,但那款初代产品并没有改变游戏规则。它是一个还不错的智能手机,但不足以真正吸引世界的注意力。所以团队继续努力,因为他们知道,Android 要实现其潜力,还有很长的路要走。
第三十五章:培根星期天
秋天的预兆
漂浮在新鲜清爽的微风中
散发着培根的香气
—迈克·克莱伦
2009 年末,也就是 1.0 版本发布一年后,安卓开始了额外工作时间的制度,启动了培根星期天的传统。以前大家都是经常加班。但渐渐地,人们开始把周末时间不用来工作了。不过安卓依然保持着那种生死存亡的紧迫感(尽管有更多的人来分担工作量)。发布截止日期至关重要;他们必须按时完成。因此,在发布的最后阶段,管理层鼓励大家在周日早晨来办公室,承诺会有丰盛的早餐自助(当然,还有大量的工作)。参与并非强制,但不是每个人都会在周日来。不过大家都知道还有很多工作要做,团队的努力可以帮助完成。
库罗西·洛克海默(Hiroshi Lockheimer)想出了这个主意。“我们在 Droid 的进度上落后了——我们大概已经落后到了第四个进度表——那是个大问题。那时有一个大规模的发布,背后有很多营销支持,所以我们就想,‘完了,怎么办?必须周末加班,搞定它。’”
“我想让它有趣。我喜欢培根。回头看,不是每个人都喜欢培根,所以培根可能不是最好的选择。我现在已经不怎么吃了,事实证明它对健康不好。”
“我们有发布任务在前。我们有需要发货的设备。这些 OEM 厂商需要我们在某个日期前提供软件,否则他们会错过假日季节。那时将会一团糟,安迪会很生气。”
“很明显我们需要更多时间。我能想到的唯一办法就是周末加班。所以周日——不是每个周日——但到了夏天,这成了一个...回头看,算是一个有点悲伤的传统。”
到了早上 10 点(要让大多数工程师在那之前到办公室实在不容易,不管有没有早餐),就会准备好一桌丰盛的早午餐,包括一大盘培根。大家走进餐厅,吃饱后和同事们聊一聊,然后回到工位继续工作。
当时负责框架团队的迈克·克莱伦(Mike Cleron),以他会给工程团队发俳句而闻名。他为培根星期天写了一些俳句:
星期天带来奇异的景象
安卓机器人与致命虫子作战
生活,还是糟糕的科幻片?
迷失在无眠的迷雾中
心志坚韧,脑力昏暗
培根,赐予我们力量
培根星期天在 2013 年秋季团队发布 KitKat 时就结束了。团队规模扩大了,所以有更多人可以帮助完成截止日期的工作。而且,发布的频率不像早期那么高了,所以也没有那么频繁的时间表危机。最后,管理层认识到该休息了,人们渴望找回他们的周末生活。
所以培根星期天活动停止了。团队并不想念它们。^(1)
第三十六章:来自巴塞罗那的明信片

GSM 世界移动通信大会(MWC)是移动行业的首要商业活动。公司和个人聚集在一起,听取该领域的最新发展,结识合作伙伴,推销自己的想法,并了解竞争对手的动向。
这个活动在 Android 的早期尤其有趣,因为这个领域随着智能手机功能的不断演变而快速变化。Android 领导团队每年都会跋涉到现场,展示 Android 在做什么,并看看生态系统和各种潜在合作伙伴公司有什么新动态。
每年,Andy 都会去巴塞罗那的 MWC,看到 Android 需要融入的功能,以保持领先或保持竞争力。他将报告发回 Mountain View,要求开发这些新功能,而这些功能通常会出现在发布的最后阶段,导致团队在发布前的这段时间里不得不迅速投入到功能开发中,而此时产品本应专注于发布前的质量和稳定性。
这些年度事件被称为来自巴塞罗那的明信片,在这些事件中,Andy 会随意地提出一些功能请求,这些请求通常已经太晚无法包含在发布版本中……但团队还是匆忙地去实现,因为这是 Andy。
Hiroshi 记得这些迟到的功能请求。“那时我会发这些邮件说,‘我刚和 Andy 开完会,他真的希望在我们发布之前修复这些问题。’这总是和 MWC 时间重合。有两个原因。首先,那时候通常是我们的维护版本发布计划,所以我们会在秋天做一次发布,然后在那个时候有一个大的后续维护版本发布。所以它通常发生在发布周期的末尾,我们正试图获得发布批准。那时 Andy 是最大的批准者。另一个原因是因为我和他在巴塞罗那,我可以直接给他看:‘Andy,我们得发布这个东西。看看,你准备好了吗?’然后几乎每次,他都会指出一两件事情,这几乎成了他的风格。”
Andy 的迟到请求也是发布计划和软件开发周期固有延迟的结果。“从我们完成软件到它真正出现在消费者手中之间有一个滞后的时间。他不喜欢这种延迟,所以他不想等。当我们说‘下一个发布’时,他知道那意味着六个月、九个月甚至一年的时间,他就会说,‘我不想等那么久,现在就做,发布之前先做完。’
“所以我就会收起尾巴,给团队发邮件说,‘抱歉,不过……’”
第三十七章:竞争
今天,苹果将重新定义手机。
—Steve Jobs(iPhone 宣布,2007 年 1 月 9 日)
iPhone 于 2007 年 1 月宣布,并于 6 月发布,发布时相隔六个月。该设备依赖于触摸屏^(1)进行用户交互,深刻影响了消费者和整个行业,改变了世界对智能手机的定义,也影响了 Android 需要做什么才能在不断发展的智能手机市场中竞争。
当时 Android 团队的一位工程师曾说过一句话,后来在多个地方出现过:“作为消费者,我非常震惊。我立刻就想要一个。但作为 Google 的工程师,我想,‘我们得重新开始了。’”^(2)
这句话暗示了 iPhone 导致 Android 改变了一切,并重新启动了其开发计划。
但这并不完全正确。
确实,Android 的计划发生了变化,但团队并不需要重新开始。相反,他们需要重新优先排序并调整产品进度。
当 iPhone 宣布时,Android 团队正全力投入开发。他们正在开发的设备叫做 Sooner,之所以这么命名,是因为他们希望它比 Android 的真正目标设备 Dream(基于 HTC Dream 硬件)更早发布。Sooner 没有触摸屏,而是依赖硬件键盘进行 UI 导航,这是在触摸屏成为必备功能之前,手机的常见用户体验……
Dream 设备确实配备了触摸屏,而 Android 平台正在设计中以支持这一功能。但 Dream 计划稍晚发布,而团队则专注于尽早推出 1.0 版和 Sooner 设备。突然间,触摸屏功能必须被优先考虑,并从未来设备转移到首个设备上。这个首个设备也因此需要相应改变。
Sooner 被放弃,开发重点转向了 Dream 设备(该设备最终作为 T-Mobile G1 在美国发布)。Brian Swetland 谈到团队的转变时说:“当 iPhone 发布时,决定是:我们要跳过发布 Sooner,尽快发布 Dream,因为发布一款 BlackBerry 风格的设备,在 Steve^(3)发布 iPhone 之后,根本没有意义。”
Dianne Hackborn 喜欢计划的变化,并将其视为完成平台的机会。“如果它发布了,就不会有多进程。我对此感到非常有压力。我很高兴我们放弃了 Sooner。软件进度与硬件进度根本不匹配。”
与此同时,团队也在构建平台能力,以支持 1.0 版中的触摸屏功能。Jason Parks 说:“一旦我们转换,Marco [Nelissen] 得到触摸面板并进行了黑客修改(4),我们就有了触摸功能。”(5)
斯威特兰谈到了关于 Android 因触摸屏而完全重新开始开发的传闻。“我觉得我们应该感到荣幸,他们认为我们能在三个月内完全重置并重建整个世界,而不是认为我们提前几年就开始建设适应性 UI 和工具,让我们能够重新构造这个世界,且所有这些工作都提前完成了。”
但是团队中对于这一变化也有些许顾虑。迈克·弗莱明说:“我很沮丧,因为我们没有发布。我觉得如果我们发布了 Sooner 产品,我们本来可以在 iPhone 之前推出。”
无论如何,团队在初次发布后肯定在讨论 iPhone,讨论得很多。《布雷迪一家》是 1970 年代初期的一部经典美国情景喜剧。在其中一集中,简厌倦了她姐姐玛莎总是得到所有的关注。某一时刻,简喊道:“玛莎,玛莎,玛莎!”在 iPhone 发布之后不久,当 Android 大楼里充满关于新设备的讨论时,安迪给团队发了一封邮件,内容是:“iPhone,iPhone,iPhone!”
Android 获得了一些关注
iPhone 让很多人投向了我们的怀抱。
——克里斯·迪博纳
在史蒂夫的 iPhone 演示后,电话铃声响个不停。因为苹果并不会将这些技术授权给你——那你该怎么办呢?
——布莱恩·斯威特兰
iPhone 的发布影响了所有手机制造商,波及整个移动产业,带来了恐慌,最终,颇具讽刺意味的是,这也成为了 Android 能够在市场上站稳脚跟的主要原因。
当 iPhone 发布时,用户看到了智能手机的新表现,具有更多功能和触摸屏驱动的用户界面。但运营商和制造商看到的是一个可能的垄断正在形成,一个将把他们排除在外的垄断。
iPhone 将只有一个制造商:苹果。所有没有名为“苹果”的设备制造商将被排除在这个市场之外。而且,iPhone 最初将在每个市场只与一个运营商合作(例如美国的 AT&T),确保在该独占合同到期之前,其他运营商无法从 iPhone 用户(及其宝贵的数据使用)中受益。
突然间,那些之前对谷歌心存恐惧或置之不理的公司,不仅开始回复谷歌的电话;他们甚至主动联系谷歌。他们需要一款可比的智能手机产品,而 Android 提供了比其他方式更快实现这一目标的机会。
iPhone 的发布“吓坏了行业,”伊利扬·马尔切夫说。“当时没有任何东西能和它相提并论。坦白说,我们也没有;我们花了一些时间才达成共识。但那时,市场上没有其他选择。”
因此,Android 团队继续开发操作系统,并与这一日益壮大的合作伙伴团队合作,最终提供了一个平台,供他们共同使用,以便为不断发展的智能手机市场打造各自的产品。
第三十八章:与此同时,在库比蒂诺……

Bob Borchers 曾是苹果 iPhone 产品营销的高级总监^(1),负责 iPhone 的开发和发布。
当 iPhone 发布时,Bob 出现在了苹果官网的原版 iPhone 教程视频中。这个视频令人印象深刻的地方,不仅仅是它是一个 iPhone 教程,或者它有 Bob 的身影,而是它没有由史蒂夫·乔布斯出演。苹果在业界因将公司大部分高管隐藏在严密的门后而闻名,只有少数人被选中作为公司面孔代表。那时(当然)主要是史蒂夫·乔布斯。
一位在那里工作的朋友向我解释过。苹果是一个消费品牌。与谷歌或微软这样的公司不同,它不是关于技术的,也不是关于工程师和工程本身,而是关于那些恰好用技术构建的消费产品。向世界展示一个非常光鲜、精致且一致的形象是这种消费品牌策略的一部分。
Bob 解释了他是如何出现在那个视频中的。“当史蒂夫介绍 NeXT 时,他做了一个视频,坐下来一个半小时,向大家介绍 NextStep 操作系统以及硬件,展示所有的优点,并帮助人们在 NextStep 上构建他们的第一个程序。当我们在思考如何向世界介绍 iPhone 时,我们采用了那个模板,决定‘在这里再做一次’。最初,我们的工作是写一个粗略的脚本,由我来做测试主持人。结果,那个测试环节变成了几个月的黑衬衫试镜。”当团队准备录制最终版本时,史蒂夫太忙了,所以 Bob 接下了这个工作。
当时,苹果内部关于谷歌正在发生的事情有很多传言。“有传闻说谷歌将要做一些关于移动操作系统的事情。这不仅仅是‘会有一款令人惊叹的硬件’,而是‘他们要打造一个平台,供其他人使用’。”
Bob 能够确认这些谣言的时间框架,因为那时他与谷歌有一个会议。“2006 年 10 月。我记得,因为我第一次和我们谈判的团队在[谷歌]开会时,首席产品经理穿着修女服出现。2006 年 10 月,苹果、iPhone、谷歌、地图的第一次碰撞发生在万圣节。我和一位修女坐在会议室里待了 2 个小时。还是一位男修女。”
但是,为什么 Apple 特别关注 Google,尤其是考虑到 Google 在移动设备方面几乎没有任何经验呢?在移动领域已经有了很多其他竞争者,包括 RIM、诺基亚和微软。“微软已经在市场上推出了 Windows Mobile。我们的分析是,微软不懂硬件,所以那是一个糟糕的体验。其他所有的竞争者都不懂软件。我们认为,软件将是主导移动世界的关键。”
“Google 的重大威胁是,Google 对软件和服务的了解。事实上,可能比 Apple 更了解。所以我认为根本的担忧是,这里有 Google,一家曾经在大规模构建软件和服务的公司,它可以并且会对像 iOS 这样的新平台构成重大威胁。”
“另一个问题是,Google 是唯一一家在与运营商合作时,没有现有业务需要冒险的公司。”
Apple 非常关注第一款 Android 设备 G1 发布后的结果。“我记得在它们上市的第一天,我去了旧金山的商店买了一部,然后带回库比蒂诺玩。软件体验是……我们看到了潜力。”实际的 G1 产品并没有在库比蒂诺引起太大的恐慌。[2]
在他们看到 G1 设备之后,Apple 对 Android 并不那么担心,至少对 G1 不太担心,因为他们确实认为自己是在产品层面上竞争,而不是平台层面:“我们当时并没有把 iOS 看作一个平台。当我们正式发布第一个 SDK 和 App Store 时,大约是两三年之后,那时我们才开始把它当作一个平台来考虑。”
与此同时,Android 领先于 Apple 进入了应用市场,Android 1.0 搭载了 Android Market 应用程序,允许开发者分发自己的应用程序。iPhone 最初发布时根本没有 App Store,也没有计划提供。
在 iPhone 发布后,人们对更多应用程序的需求不断增加。“开发者的需求非常大,大家都在请求。第一步是去构建 Web 应用程序。这是完美的,因为当时没有人在手机上安装软件,但你可以拥有类似应用的体验。我们的希望是,Web 应用会成为主流。”
但最终,Apple 在消费者和开发者的压力下,提供了一种方式,让开发者为 iPhone 提供高质量的原生应用程序。“我们完全专注于消费者体验,而消费者告诉我们,他们希望有更高质量的应用程序,同时开发者也告诉我们,他们希望开发出更高质量的应用程序。”App Store 被推出,采用了比 Android 更加精选的模式,符合 Apple 更加严格控制整体体验的方法。
Bob 还评论了 iPhone 对运营商的影响。iPhone 在美国与 AT&T 签订了独家合作协议,并且在其他国家也有类似的独家运营商合作协议。这迫使其他运营商,如 T-Mobile 和 Verizon,寻找其他选项。“我们早期就确定了要在每个市场与一个运营商独家合作。这意味着在每个市场都会有两到三个其他运营商需要以某种方式填补这个空缺。所以,Android 就在这个空缺中找到了机会。”
Bob 于 2009 年离开了 Apple^(3),也就是在 iPhone 发布两年后。^(4)
第三十九章:SDK 发布

Brian Swetland 和 Iliyan Malchev 录制了一段介绍视频,该视频于 2007 年 11 月 5 日发布^(1)。(图片由 Peisun Wu 提供。)
通过为开发者提供一种新的开放性,使他们能够更具协作性地工作,Android 将加快推出新颖且具有吸引力的移动服务的步伐,供消费者使用。
—开放手机联盟新闻稿,2007 年 11 月 5 日
在发布 1.0 版本、源代码或任何物理硬件之前,Android 就已经发布了早期版本的 SDK。提前发布 SDK 为开发者提供了充足的时间来了解 Android,并构建和测试他们的应用程序。对平台的早期访问也给团队提供了一个机会,收集开发者的反馈,指出在 1.0 发布前需要修复的问题。
2007 年 11 月 5 日:开放手机联盟
2007 年 11 月 5 日,Google 宣布成立开放手机联盟^(2)。OHA 是团队所构想的生态系统中的重要一步。与由 Apple 和 Microsoft 主导的传统模式截然不同,在这些传统模式中,单一公司控制着平台,OHA 承诺提供一个开放源代码的平台,所有公司都可以使用。它是由运营商、硬件制造商和软件公司组成的联盟,包括:
-
移动运营商,包括 T-Mobile、Sprint Nextel 和 Vodafone 等公司
-
手机制造商,包括 ASUS、Samsung 和 LG
-
半导体公司(制造集成到手机中的芯片的公司),如 ARM 和 NVIDIA
-
软件公司,包括 Google 和 ACCESS^(3)
该声明承诺了许多美好的未来,但它仅仅是一份新闻稿——充满了美好的词句,描绘着光明的未来,却没有实际产品展示出来。
11 月 7 日至 8 日:行业接待
不属于 OHA 的现有移动领域参与者似乎对这一声明不太看重。
11 月 7 日,在 OHA 宣布两天后,Symbian 的高管 John Forsyth 在接受 BBC 采访时表示:“搜索和移动平台是完全不同的事情。这是一个昂贵、艰巨、有时甚至是非常不吸引人的工作——每天支持客户发布手机。这是 Google 环境中几乎没有经验的领域。他们说要在明年年底推出手机,但那款手机不会引起开发者的兴趣。”
第二天,微软时任 CEO Steve Ballmer 在新闻发布会上表示:“他们的努力目前只是纸面上的一些文字,很难与 Windows Mobile 进行明确的比较。现在他们有一份新闻稿,而我们有很多很多的客户,优秀的软件,众多的硬件设备。”
空气中似乎弥漫着一种虚拟软件^(4)的感觉。新闻稿是一回事,但发布一个手机平台则是另一种完全不同的软件挑战。
11 月 11 日:SDK 发布
11 月 11 日,在 OHA 宣布后的六天,Android SDK 发布了,版本被亲切地命名为 m3。^(5)
当初 OHA 宣布时,SDK 已经完全准备好了。但决定先发布新闻稿,并让它在发布代码之前流传几天。这为行业情绪和普遍的误解提供了滋生的空间。六天后,团队发布了实际的软件,使得这个宣布变得非常真实。
既然 SDK 已经发布,应用开发者可以下载它,进行尝试并开始开发应用,但这远不是最终版本。例如,第一次发布的版本有一个模拟器,看起来像 Sooner 设备(配有硬件键盘,占据了比小屏幕更多的空间,但也具备了实际 Sooner 设备所不具备的触控支持)。这个模拟器还已经有许多功能性应用。Android 确实是一个基本完整的系统,尽管没有可以发布的物理设备,并且 API 也尚未最终确定。

第一次 SDK 发布中的模拟器类似于原始的 Sooner 设备,配有硬件键盘,尽管与 Sooner 不同,它还具备了功能性的触摸屏。

2007 年 12 月发布的 SDK m3-r37 版本中包含的模拟器。
在第三个 SDK 版本 m3-r37a 中,发布仅一个月后,模拟器提供了一个更现代的设备,配有更大的触摸屏。
值得注意的是,所有这些 SDK 仍然可以在 www.android.com/ 网站上获取,包括仍然能够运行的模拟器。你为何想花时间使用这些 Android 的预发布版本是另一个问题,但能够使用它们还是挺酷的;Android 一直以来都强调开放性,显然这一点也延续到了从未实际搭载运行硬件的过时操作系统版本上。
名字代表什么?
给产品命名可能是一个困难的任务,特别是当律师参与其中时。^(7) 有一个内部代号供团队使用是一回事。它可能是任何名称,因为外界可能永远不会知道,也不会与其他人或公司的产品或名称产生冲突。^(8) 但当这个内部产品变得外部化并公开时,事情就变得复杂了。你必须做商标搜索。当别人已经拥有你想要的名字时,你必须弄清楚该怎么做,通常这意味着要想出一个新的名字。
在发布前的几周,人们担心Android这个名字无法在外部使用。黛安娜说:“我记得我们当时非常担心可能需要更改名字,因为那个时候‘Android’这个词几乎无处不在——在 SDK 上,到处都是。如果我们不得不在 API 中更改它,那将是一团糟。”
团队还集思广益,提出了其他一些选项,包括Mezza。丹·莫里尔解释了这个名字背后的逻辑:“它本应意味着‘夹层’,就像是中间件的作用。”不用说,没人喜欢这个名字,最终做出了正确的决定。
Android 开发者挑战赛
发布一个新的软件平台的其中一个难点是让任何人都开始使用它。当 SDK 发布时,全球除了 Android 团队之外没有任何用户,直到 1.0 版本发布之前,Android 设备都无法购买,所以这个数字可能需要好几个月才能发生变化。团队必须想办法让开发者对投入时间和精力开发这个没有用户、充满不确定性的全新平台产生兴趣。
所以团队想出了 Android 开发者挑战赛。2007 年 11 月 12 日,关于 Android 的第一篇博客以一个引人注目的钩子结束:“我们真的很期待看到开发者在开放的移动平台上创造出所有令人惊叹的应用程序。事实上,你可能还想把你的应用程序提交到Android 开发者挑战赛——这是由 Google 赞助的 1000 万美元挑战赛,旨在支持和表彰为 Android 平台开发出优秀应用程序的开发者。”
2008 年 1 月 3 日,比赛正式启动。团队接受参赛作品直到 4 月 14 日,然后将它们送往全球的评审团,评选出前 50 名应用程序。这 50 名开发者每人获得了 25,000 美元的奖励,并要求提交第二轮作品。在第二轮中,前 10 名应用程序获得了每个 27.5 万美元的奖励,接下来的 10 名则每个获得 10 万美元。如果你算一下,这次比赛 Google 一共发放了 500 万美元的奖金。
因为这些应用程序当时连用户都无法使用,所以很难说团队是否得到了应有的回报。那时,Android 外的人连一台可以运行这些应用程序的设备都买不到;而决赛选手的名单在 2008 年 8 月公布,距离第一台 G1 手机上市整整有两个月。但这个挑战赛确实吸引了开发者的兴趣,因为有 1,788 个应用程序参加了这个比赛,尽管平台没有用户且发布日期未知。
这项活动不仅让开发者对平台产生了极大的兴趣;将所有这些开发者引导上手并获得他们的反馈,也帮助平台团队在最终发布 1.0 版本时更好地完善了系统。Dirk Dougherty 解释说:“我们必须弄清楚如何编写应用,然后再将这个过程解释清楚。处理所有的反馈。今天我们可能会收到大量反馈,但这是一个全新的 API 接口,运行在一个全新的平台上,以前没有人真正用这种方式接入传感器等设备来编写应用。所以出现了大量我们没有想到的全新使用案例。”
即使是评审应用的过程也颇为独特……Google 希望能够请到全球知名的评审来评判,这些评审在开发者社区中有一定的知名度。Google 希望能够让这些远程评审的工作变得简单,但那时 Android 的开发并不“简单”。为了运行一个应用,评审必须先在自己的电脑上安装 SDK,运行工具,启动模拟器,运行命令将应用加载到模拟器中,并启动应用。要评审近 1800 个应用,这根本无法扩展。
所以 Google 为每一位评审发送了预装工具的笔记本电脑,这些工具是 Dan Morrill 的开发者关系团队编写的,能够启动模拟器,并提供一个界面来选择测试的应用,自动安装并在模拟器上运行。“我们给全球的每一位评审都寄出了笔记本电脑。那真是疯狂!这些笔记本电脑大多数都没能归还。有一个评审把它寄回时,包装盒里塞满了各种毛绒玩具,不知道为什么。”
初赛的前 50 名获奖者仍然可以在 Android 开发者博客上找到;^(11) 名单上的第一个是由 Android 团队的 Jeff Sharkey 创作的“AndroidScan”。^(12) 不,他并没有通过以 Google 员工身份参加比赛来作弊:Jeff 是因为平台团队看到他在比赛中的表现才被招募的。“我被邀请到山景城,参与开发机密设备(G1)。我当时兴奋得完全没在山景城时继续开发那个应用。相反,我开发了另一个应用^(13),这个应用使用超级优化算法进行区号到城市的来电显示查询,不需要网络连接。”后来,Jeff 继续开发 AndroidScan,并将其改名为 CompareEverywhere,最终成为了 10 位总冠军之一。
一旦比赛结束,团队继续完善产品,并在 2008 年 10 月发布了 1.0 版本。2009 年 5 月,他们举办了第二次挑战赛,奖池再次提供了五百万美元。但与此同时,Android 已经吸引了真正的用户,Android Market 也开始营业。现在,Android 拥有了一个真实的用户和开发者基础,不再仅仅是一个预发布平台的参赛者。
第四十章:1.0 版本的准备

从 2007 年 11 月 SDK 的初始发布到 1.0 版本发布之间,几乎过去了一年,1.0 版本与 G1 手机几乎在一年后发布。那么在这段时间里究竟发生了什么呢?
首先,实际上这段时间并没有你想象的那么长。
根据情况,有些软件产品可以很快发布。如果你只是更新网页上的一些代码,你可以立即发布。如果该版本中有一个 bug,修复后可以立刻重新发布。但如果你发布的是一种不像简单更新网站那样容易分发给用户的产品,你就需要进行一定程度的测试和稳定性处理才能发布。你不想让用户经历一次繁琐的更新过程,却发现有一个严重的 bug,并且还需要再次更新。这样至少要耗费几周时间^(1)。而像 G1 这样的硬件发布,除了其所依赖的软件,还涉及更多的时间。
Android SDK 仅仅是软件,团队本可以在发布前继续更新,修复 bug(正如他们在 1.0 版本发布前的 Beta 阶段所做的那样),直到宣布“完成”。但这个版本需要在 G1 手机上运行良好,这涉及到完全不同的约束。手机需要经过运营商严格的合规性测试,这意味着团队必须比单纯发布一个新的 SDK 版本提前完成工作。Romain 谈到过:“定稿时间是在商店发售前一个月。但在此之前是大约三个月的运营商测试。”因此,为了确保 G1 能够在 10 月中旬上市,团队必须在 2008 年 6 月(即 SDK 初始发布后仅七个月)基本完成平台开发工作(除了修复最终测试阶段出现的关键 bug)。
在这七个月里,许多问题需要解决,包括完善公共 API 的细节、进行关键性能优化以及修复各种 bug。
兼容性的成本
发布前,公共 API 需要进行打磨。SDK 处于 Beta 阶段,鼓励开发者为其编写应用,但 API(方法名、类名等)并非最终版。然而,一旦 1.0 发布,API 就固定下来了,无法更改。在发布版本之间更改 API 意味着使用这些 API 的应用可能会在用户设备上神秘崩溃。
这种兼容性动态在像 Android 这样的平台上尤其明显,因为开发者无法强制要求他们更新应用程序,也无法强制用户安装这些更新。假设一位开发者在 10 年前编写并上传了一款应用到 Play Store。某个地方,有人正在愉快地使用这个应用。然后该用户将手机升级到更新的版本。如果该更新版本改变了那个旧应用所使用的 API,它可能无法正常工作,甚至可能崩溃,显然这不是 Google 想要的。所以,旧的 API 会一直保留并得到支持……太久……太久了。
因此,Android 团队开发者的诀窍是,对任何新的 API 都要非常谨慎,因为这个团队必须永远使用它。当然,总会有错误,或者事后你会想“如果当时做得不一样会怎样”。^(2) 菲库斯·柯克帕特里克(Ficus Kirkpatrick)观察到:“你可以尝试设计完美的东西。然而,当你在实验室里忙着打磨它时,总会有人出来做出某些东西,让你显得不再重要。”
团队致力于让 API 达到他们满意的程度,并愿意让这些 API 长期存在。1.0 版本前的一些更改,如方法或类名,比较小。但是有些 API 被完全移除,因为它们并不是平台希望永远支持的内容。
罗曼·盖伊(Romain Guy)说:“在 2008 年的很大一部分时间里,我都在清理 API,并尽可能地从框架中移除不必要的内容,直到我们发布。”例如,他移除了 PageTurner 类,这个类实现了一个酷炫的撕纸效果。它最初是为早期版本的计算器应用程序编写的,用来在清除显示时展示一个有趣的动画。但计算器的设计发生了变化,不再使用这个动画。由于这个效果过于具体,属于一个小众的效果,因此不适合保留在公共 API 中,所以该类被删除了。

计算器应用的撕纸效果很酷,但并不是普遍实用的。因此,它在 1.0 版本前就被从平台 API 中移除了。
当时作为外部开发者的杰夫·沙基(Jeff Sharkey)评论了项目在这一阶段的 API 波动:“在 1.0 发布之前的多个预览版本中,Android SDK 的部分内容经历了相当动荡的变化。UI 组件在每个快照中都在被添加、移除或重新设计^(3)。一些完整的功能被彻底砍掉了。”
这并不是说没有一些糟糕的 API 悄悄进入并在 1.0 之后继续存在(见前面的脚注评论关于“制造未来的遗憾”)。一个例子是 ZoomButton,这是一个用于将长按解释为多个点击事件的工具类,然后将这些事件发送到处理缩放的其他逻辑。ZoomButton 本身并没有进行任何缩放操作。实际上,它什么也没做,除了将一种输入类型(长按)重新解释为另一种(多个点击)。但不幸的是,它在 1.0 之后继续存在,直到多年后,在 Oreo 版本中才被弃用^(4)。
性能
在这个阶段,另一个关键的工作领域是性能。尽管当时的硬件相比早期的移动设备已经有了很大的进步,足以支持智能手机的存在,但 CPU 仍然非常有限。此外,手机上的每一项操作都会消耗电池并缩短用户需要充电的时间。因此,平台和应用工程师们尽力让一切运行得更快、更流畅、更高效。例如,罗曼·盖伊和其他 UI 工具包团队的成员花了大量时间优化动画和绘图逻辑,以避免做不必要的工作。
错误,错误,错误
G1 的硬件终于在 SDK 发布时开始广泛供内部使用,团队也能开始在真实硬件上测试他们的代码。一旦设备可以大量获得,大家也能将 G1 作为日常使用的手机,这也产生了许多需要在 1.0 版本发布前修复的 bug。
罗曼说:“那段时间发生了什么?大量的调试。”
彩蛋
在 1.0 版本中没有实现的一项功能是一个彩蛋^(5),列出了所有参与发布工作的人的名字,这让人想起经典的 Macintosh 团队签名,这些签名曾装饰在电脑机箱内部。罗曼·盖伊实现了这个功能,但它最终没有发布。
“你可以为所谓的‘秘密代码’在拨号器中注册一个意图。当你拨打像##,一个号码,##,它基本上是一个系统命令。有时你的互联网服务提供商可能会让你输入这样的内容,以要求你执行某些操作。”
“启动器注册了其中一个代码。如果你输入了它,启动器会被唤醒,并且会在我隐藏在元数据中的一个图标里找到参与 Android 1.0 开发的团队成员的名单。它会弹出一个 UI,滚动显示这些名字。实现这一功能的代码被写在 Java 源代码中的注释里。所以,这段代码是被隐藏起来的。”
“我们把它变成了一个功能。我们开始招募更多的人,包括承包商。我们加入了越来越多的功能。最终它被放弃了,因为有人担心我们会忘记某个人。”
“所以它曾是一个有趣的小彩蛋,但最终被过度产品化了。”
最近发布的 Android 系统中有彩蛋,大多数是由系统 UI 团队的 Dan Sandler 实现的。这一 Android 传统开始于 1.0 发布之后的几个版本,也许是当时团队终于有时间喘口气,开始考虑一些非关键性的事情。或者也许只是因为像 Dan 这样具有艺术技能、幽默感和编码速度的人可以做成这件事。长按系统设置中的版本信息会弹出……某些内容。有时候它只是一个漂亮的视觉效果,有时候是一个简单的游戏或应用程序。但它从来不是一份产品开发人员的名单,因为那样会太复杂。
应用程序
团队在 1.0 版本发布前也花了一些时间,尤其是在版本接近完成时,当时只允许修复关键性的 bug,进行应用程序的编写。Mike Cleron 说:“这就是我大部分应用程序编写生涯的地方。在框架上进行调试。”
Mike 和 Romain,都是充满激情的风光摄影师,他们致力于摄影应用程序的开发。编写真实世界中的应用程序不仅为用户提供了更多功能,也帮助平台开发人员从应用程序开发者的角度理解平台,从而推动未来版本中更好的 API 和功能的开发。当然,它也有助于发现可以修复的 bug。
第四十一章:1.0 版本发布

在科技行业,软件发布通常会通过为团队提供纪念 T 恤来庆祝。这款 1.0 版本发布的 T 恤是 Android 发布中的第一款类似纪念 T 恤。(图片由 Chiu-Ki Chan 提供)
Android 1.0 的发布分为四个阶段,于 2008 年秋季进行。
9 月 23 日:Android SDK
发布的第一部分是 SDK 本身,1.0 于 2008 年 9 月 23 日发布。一方面,1.0 只是自从 10 个月前的初始 m3 发布以来的又一次更新,直到 8 月 18 日才发布了 0.9 版本,距离它只有短短五周。
但 1.0 版不仅仅是另一个迭代版本;它,嗯,就是 1.0 版。它代表了团队对 Android 官方支持的 API 的最终思考,因为从现在起,如果没有打破已经构建的应用程序,就无法再更改 API。
按照惯例,Google 并未对这个开发者产品进行大肆宣传。没有新闻发布会;只是在服务器上上传了一些文件,并附带了这版中的修复说明。即便是发布说明的开头句子也非常克制。如果你不知道你在看什么,可能会以为这只是另一次更新(实际上,在某种程度上,它确实是)。

1.0 发布的重大爆炸性新闻的发布说明... 语气很克制。
但这些发布说明确实包含了一个重要的功能缺失道歉:“我们遗憾地通知开发者,Android 1.0 将不支持点阵打印机。”
9 月 23 日:T-Mobile G1 公布
Google 没有为面向开发者的 SDK 发布会召集媒体,但他们确实在纽约市的新闻发布会上与 T-Mobile 一起上台,宣布了将运行 1.0 的消费者手机。与 1.0 SDK 一同发布的当天,代表们讨论了新设备,并且 T-Mobile 发布了一份题为“T-Mobile 推出首款 Android 手机 T-Mobile G1”的新闻稿。
G1 设备将配备触摸屏、滑动开启的 QWERTY 键盘以及轨迹球。它将运行 Google Maps、搜索,并提供来自 Android Market 的应用程序。设备配备三百万像素的相机,并将运行 T-Mobile 的全新 3G 网络。它将以合约价 179 美元或解锁版 399 美元的价格销售,初期将在美国推出,随后几周扩展到其他国家。
而且,它将在一个月后上市。顾客可以预订 G1,但必须等到 10 月 22 日才能拿到。
10 月 21 日:开源
就在 G1 发布前一天,1.0 的源代码被发布了。再次提醒,这次的开发者发布没有任何盛大的活动。实际上,这次甚至没有新闻稿,只有一篇简短的三段式内容发布在 Android 开发者博客上,标题是:“Android 现在是开源的。”
这不算什么。但它是一切。
Android 从诞生之初就计划推出开源平台。它将这一构想向投资者、谷歌、团队成员、运营商和制造商合作伙伴以及全球开发者进行了推介。如今,在首个公开 SDK 发布 11 个月后,1.0 版本发布 1 个月后,它兑现了所有承诺,将所有代码公开,供大家查看和使用。
10 月 22 日:T-Mobile G1 发布
10 月 22 日,在 Android 开源的次日,G1 终于对谷歌以外的人开放,大家可以尝试并购买。

T-Mobile G1
当 G1 在旧金山 Market 街的 T-Mobile 店铺开始销售时,Romain Guy 在场,拍下了第一位购买者的照片。如今,想象谁在什么地方购买手机似乎不再重要,但在当时,这第一笔购买标志着开发团队多年辛勤工作的结晶;看到他们的努力走向现实,并看到人们排队购买,令人兴奋。那天在店里还有另一位人物,他是 iPhone 的产品营销高级总监 Bob Borchers。他当时为自己的团队购买了一部 G1,让他们回到苹果公司后好好体验。

Michael Morrissey 和他的孩子们在 G1 开售的第一周参观了 T-Mobile 店铺中的 G1 展示。(图片由 Michael Morrissey 提供。)
G1 是制造商(HTC)、运营商(T-Mobile)和谷歌之间合作开发的第一款设备。最初,这些谷歌合作设备的想法是展示最新版本的功能。同时,这些手机也让团队能够验证新功能,确保所构建的东西能够在真实硬件上运行。对于 G1 来说,这款硬件帮助团队验证了 Android 平台是否可行,是否能为功能齐全的消费设备提供支持,并为更多平台功能和设备的到来提供了基础。
第四十二章:G1 接待
G1 并没有超越 iPhone 的销量,没有成为全球热销产品,也没有成为每个人都必须拥有的手机。
评测普遍认为它是...有趣的。硬件并不差,虽然屏幕确实很小。它不支持视频录制。而且除了预装的 Google 应用外,并没有很多必备应用。
在 Android 团队中,反响也是褒贬不一。正如 Fadden 所说,“G1 几乎达到了好的边界,但它有点笨拙、不流畅。”
Dan Egnor 同意:“它有点像一个爱好者设备。有些人对此很兴奋,但在很多方面,它其实是个挺差的设备。它显示了很大的潜力。但要让某些人去采纳它?它并不是那种一上架就飞 off 的东西。”
Dave Burke 讲述了 G1:“给人的印象是:‘哇,这东西真是很复杂,能做很多事。如果说有什么问题...那就是它做得几乎太多了。’它有一个键盘,一个触控板,一个滚珠鼠标和触摸屏。它几乎什么都有。所有这些传感器。一开始你会感觉,Android 似乎想做一切。我记得当时在想,什么功能会存活下来?是键盘和触摸屏会存活吗?那个滚珠鼠标真的会成为关键吗?大家都意识到这个东西非常强大,但也完全不确定它可能只是昙花一现,最终会失败。大家并不清楚。”
Dianne 说:“G1 绝对是一个‘什么都要有’的设备...作为一个普通消费品,这可不是最好的东西。但它对平台来说是好的,因为我们必须支持所有这些东西。”所以,虽然它可能没有为手机创造最佳的消费者体验,^(1)它为随后的一系列设备铺平了道路,这些设备能够利用平台提供的各种功能。
假日销售是新设备一年中最重要的时期。Dan Egnor 记得与 G1 一起度过的第一个假日:“Michael Morrissey [服务团队经理] 记得圣诞节那天的高峰[来自 Danger],那时团队里没人可用,事情一团糟。所以他就说,‘我们那天要安排值班。我们要设立一个战情室。谁能在那儿?大牺牲,圣诞节当天工作……’我就说,‘我来吧,没问题。’结果什么都没发生。我们活跃度比平常多,但并没有出现特别大的激增。”
所以,G1 并没有成为一夜之间的胜利。但它有潜力。
它足够让人们认真看待这款手机。并且它的销量虽然不算压倒性,但还是达到了真实的数字。T-Mobile 报告^(2)称,六个月后,它在美国的销量已超过一百万部。这恰好是那个时间框架内,谷歌网络团队需要的设备数量,以说服他们不收回原本为 Android 服务团队配备的专门 VIP 资源^(3),否则这将给所有 Android 上的谷歌应用带来严重问题。
G1 也为人们认真看待 Android 平台提供了足够的体验。Android 终于发布到世界上了。人们能够使用设备和平台完成他们需要做的事情,这对于当时来说已经足够好了。消费者可以把 Android 当作手机来认真对待,潜在的合作伙伴也可以把 Android 当作平台来认真对待。这使得制造商看到 Android 是真实存在的,他们可以利用它来打造自己的设备,这些设备最终将比最初的 G1 更有趣、更强大。
Hiroshi 说:“G1 造就了 Android。从商业上来说,G1 并不是一个巨大的成功。G1 不错,但并没有成为巨大的销量驱动者,也没有在科技行业之外引起太多关注。但它的发布让 OEM 厂商看到了 Android 的真实存在:‘好吧,这些人实际上能够发布产品。这是一个真实的东西,不是空中楼阁。’到 G1 发布时,我们已经和所有主要的 OEM 厂商展开了讨论,最终他们成了我们的合作伙伴。”
第四十三章:43
甜点

1.0 版本发布,G1 手机上市,大家松了一口气,完成了这项艰巨的任务。然后他们又回到了工作中。
对团队来说,Android 显然还远未完成;在功能和质量上还有很多工作要做,以使 Android 更具竞争力。而且,更多的设备也在陆续推出。
在接下来的一年里,团队拼命工作,发布了多个小型的错误修复版本以及更大的“甜点”版本,最终以 2009 年底与 Droid 设备一起发布的 Eclair 版本为高潮。仅仅一年时间,团队就发布了四个主要版本:1.1(Petit Four)、1.5(Cupcake)、1.6(Donut)和 2.0(Eclair)。
Tom Moss 指出,这种疯狂的节奏是故意为之:“有两个原因:Andy 是个完美主义者,他希望产品变得更好。当产品不够好时,他个人会感到非常不满。但这也是一种战略,故意让 OEM 厂商不敢分叉,他们会说,‘等你们的分叉版本发布时,我们的新版本 Android 已经出来了,你们得重新开始。’”
“他故意推动我们每年发布多个版本,以此来阻止或使得别人不再尝试分支。”
1.0 r2:2008 年 11 月
第一个错误修复版本之所以值得注意,是因为它是第一个。1.0 版本于 2008 年 9 月发布。这个版本被安装在了当年 10 月出售的 G1 手机上。随后在 11 月发布了 r2 版本,除了各种错误修复外,还增加了一些功能和应用。
1.1 Petit Four:2009 年 2 月
1.1 版本是第一个命名的版本:Petit Four(一种小蛋糕,法语为“小烤箱”)。这是一个相对较小的版本,包含了错误修复和一些 API 的新增功能。它还为其他语言提供了本地化支持(1.0 仅支持英语),这对于这个国际化的平台来说,成为了一个重要的特性。
从这一点开始,每当“点”版本号(第一个点后面的数字)有变动时(例如 1.1 与最初发布的 1.0 相比),意味着该版本中有 API 变化。API 的变化意味着基于旧版本 SDK 构建的应用程序可以在新版本上运行(Android 始终尽力保持向后兼容性),但基于新版本构建的应用程序可能无法在旧版本上运行(因为新 API 在旧版本中不存在,使用这些 API 会导致旧系统出错)。
1.1 版本是第一个允许在 Android Market 上出售应用程序的版本。在 1.1 之前,向用户收费的机制尚未生效,因此 Market 只允许免费应用程序。
Petit Four 也是第一次将甜点名称用于 Android 版本,尽管它显然没有遵循按字母顺序依次命名的传统;这一传统从下一个版本“Cupcake”开始。
1.5 Cupcake:2009 年 4 月
Cupcake 是首个建立了连续字母甜点传统的版本。它以“C”开头,因为这是第三个主要版本,而“Cupcake”被选为 C 字母的甜点名称,因为当时负责发布的 Ryan PC Gibson 对杯形蛋糕(cupcakes)情有独钟。^(1)
Cupcake 为开发者和用户带来了一些显著的功能。首次出现了应用程序小部件(App Widgets)。现在可以进行视频录制。开发者可以开发并分发自己的键盘应用程序。此外,还新增了一种传感器和逻辑来检测旋转,因此用户可以将手机旋转至横屏或竖屏模式显示。在此之前,用户需要滑出 G1 的键盘,这样显示屏就会自动转为横屏模式。
Cupcake 版本的发布恰逢一款新设备的推出:HTC Magic。Magic 是首款仅支持触摸的设备;G1 的硬件键盘被现在大家熟悉的屏幕软件键盘所取代。
Cupcake 的发布说明中有一则对开发者和用户来说不太好的消息:“我们遗憾地通知开发者,Android 1.5 将不支持 Zilog Z80 处理器^(3) 架构。”
1.6 Donut:2009 年 9 月
Donut 版本完善了平台的一些基本功能。电信堆栈现在支持 CDMA,这是 Verizon 使用的系统(例如在 Verizon 网络上推出的摩托罗拉 Droid 便采用此系统)。框架团队完成了对任意屏幕大小和密度的支持,这对于推动不同形式因子的更广泛生态系统至关重要。^(4) Donut 还包括了语音转文本引擎。虽然它远不如今天手机中使用的系统强大,但它表明了技术的潜力。
Donut 版本的发布说明也带来了一则不幸的消息:“我们遗憾地通知开发者,Android 1.6 将不支持 RFC 2549。”^(5)

广志正在享受一个“甜甜圈汉堡”。Peisun Wu 向团队介绍了这一概念,以庆祝 2009 年 9 月的 Donut 版本发布。(图片由 Brian Swetland 提供。)
2.0 Eclair:2009 年 10 月
另一个有趣的地方是 Eclair 版本发布的时间非常接近 Donut 版本—仅相隔一个月。^(6) 当时团队在多个频繁的发布中并行工作得非常努力,实际上 Eclair 版本的开发工作在 Donut 版本发布之前就已完成。
在 Eclair 中增加了多种功能,包括动态壁纸和逐步导航。^(7) 但也许 Eclair 最值得注意的是,它与新推出的 Droid 和 Passion(Nexus One)设备一同发布,这些设备在 Eclair 发布后不久就推出了。Passion 设备是团队真正倾心的产品,但 Droid 是首个成功打入大规模消费市场的设备。
第四十四章:早期设备

一堆 Sooner(图片由 Brian Jones 提供)
如今,Android 生态系统的一个特点是几乎无限种类的设备。不仅有许多不同制造商生产的不同型号的手机,还有平板、相机、电视、汽车、手表、物联网设备,甚至是飞机上的娱乐屏幕^(1)。
1.0 之前:Sooner、Dream(HTC G1)及更多
很早的计划包括四款手机。正如 Swetland 回忆的那样,“2006 年 6 月讨论中的四款设备是 Sooner(HTC wedge)、Later(LG wedge)、Dream(HTC G1)和 Grail(摩托罗拉设备,可以一侧滑出 QWERTY 键盘,另一侧滑出数字键盘)。Grail(或其某些变种)多年来一直时隐时现。”但最终计划仅定下了 Sooner 和 Dream,关于它们的终结与发展在前面章节中有讨论。
蓝宝石(HTC Magic)
Android 的第二款旗舰设备,代号 Sapphire,是基于 HTC Magic 的。它在 2009 年春季随 Android 1.5 Cupcake 版本发布。实际硬件规格与原始的 G1 类似,尽管 Magic 有更多的内存。但最大变化是键盘:Android 终于决定全面转向触摸屏,放弃了早期 G1 上的硬件键盘。Magic 还首次支持 Android 的多点触控^(2)。
摩托罗拉 Droid
Droid 手机对早期 Android 系统的重要性,以至于它有自己的专章(第四十五章,“Droid 做到了”)。如果你愿意,可以现在去读那个章节。我等你。
热情与 Nexus
与 Droid 手机并行,团队还在研发另一款代号为 Passion 的设备。它在 2010 年初作为 Nexus One 发布。

Nexus One 于 2010 年 1 月发布,紧随其后的是摩托罗拉 Droid。
Passion 是“Google Experience”系列手机之一。Google Experience 的过程经过多年变化,曾有过许多不同的名称和合作形式。在 Nexus One 发布时,与 HTC 的合作被赋予了“With Google”这一品牌。这个口号是在工程团队中诞生的。市场部原本提出的口号是“它有 Google”。但系统团队的 Rebecca 向 Andy Rubin 抱怨:“这句话都不合语法!那‘With Google’怎么样?”Andy 说:“好的!”于是,这一联合品牌口号诞生了。
Passion 拥有当时较大的屏幕和适合手持的曲线。但 Passion 的独特之处并非硬件或软件,而是 Android 所尝试的销售模式。在美国,大家当时(现在大部分时间也是)购买手机的方式是通过与运营商签订合同。与其单独购买设备,再支付运营商费用接入其网络,人们会去 T-Mobile 商店(例如)购买他们提供的手机。手机以大幅折扣出售,并附带一定期限的合同锁定。这就是手机市场的运作方式。
但 Android 的领导层有一个想法,那就是人们应该有选择权。假如他们独立选择手机,而不是通过运营商选择手机,且只支付运营商费用以连接到他们的网络呢?这样他们就不受合同约束,用户的选择也更多了,因为他们不必从运营商店铺里那些偶然摆放的设备中挑选。
Google 没有实体店铺,因此他们在线销售 Nexus One。他们耐心等待。但事实证明,人们并不真正理解这种购机模式,也不急于去弄明白。此外,如果他们从网站上购买的手机出现问题,他们没有客服热线可以联系,也没有实体店铺可以退货或寻求帮助。
最终,Android 放弃了这个想法,Nexus One 由运营商提供。它的销量远未达到 Google 的预期,且被摩托罗拉 Droid 远远超越。
Nexus One 是 Nexus 系列中第一款手机。Nexus 手机是 Android 团队与制造商合作开发的设备,目的是创造一个整体的 Android 手机体验。团队无法控制其他制造商在硬件、软件以及可能在 Android 上层叠加的应用程序的生产与销售。通过推出自己的手机,Android 可以确保这些设备拥有他们想要的硬件(至少在硬件合作伙伴可以提供的范围内),并且拥有他们想要的软件。
Nexus 项目的另一个,或许是主要的,原因是生产一款“参考设备”。Nexus 手机向世界(以及合作伙伴)展示了该版本的 Android 所能实现的功能。但团队也确保平台可靠地支持新功能,这在硬件与软件分开开发的情况下可能会更难实现。在许多年和多个版本中,新的 Nexus 手机会与每次软件发布同时推出,展示最新的硬件进展以及 Android 的新功能。
在 Android 的历史上,Nexus 和其他 Google 帮助推出的设备的一个重要特点是它们由不同的制造商生产。这是非常有意为之的,目的是让整个合作伙伴社区都能参与到 Android 中。Google 的早期设备包括 HTC、摩托罗拉、LG 和三星的手机。
Charles Mendis 说:“Andy 和业务开发的功劳很大。我们不仅仅和一个厂商合作;我们会在他们之间切换。我们成功地让硬件领域的一些最大厂商投入到 Android 中,使它成为他们的平台,现在所有这些手机硬件都由他们制造。我们让他们觉得 Android 是大家的;Android 并不是 Google 的独占。^(3) 我认为这对它的成功起到了很大作用。”
Brian Jones 与设备分发
我是[设备]连接人员。
—Brian Jones
在每个科技公司里,总有一个你必须认识的人,才能得到最好的设备来完成你的工作。这个人是内外部所有人和他们所需物品之间的纽带。
在 Android 团队中,这个人就是 Brian Jones(大家都叫他“bjones”)。
Brian 一直是个喜欢动手的研究者。小学早期,他想知道电话是如何工作的,于是他的老师组织了一次课堂活动,并带来了她自己家里的电话。“我把它拆开,直到看到封装在蜡里的变压器。根本没有可能把它重新装好。它是蜡状的,弄得自助餐厅一片狼藉。我以前从来没做过这事,我惹了大麻烦,因为老师本来指望能带着她的电话回家晚上继续用,但那显然不可能了。”
Brian 进入 Android 团队的路径并不典型,他最初获得的是古典学的大学学位。当他搬到湾区并需要工作时,他在 Android 团队工作的 44 号楼做接待员。他结识了团队中的许多人,包括 Andy 的管理员 Tracey Cole。Brian 的建议是:“和管理员建立友谊。她们是你可能在生活中最值得争取信任的第二重要—如果不是第一重要—的人。”
2007 年春季,Tracey 开始休假,Andy 需要有人在她休假期间替代她的工作。“Tracey 说,‘我不想再去找一个临时工。Brian 是我们已经信任的人,我只希望把这个工作交给他。’所以我当了 Andy 的管理员三到四个月。”

Brian 的刻印机,放在一个小厨房区域。Brian 编程控制它开关并旋转设备,同时配合激光进行工作。(图片由 Daniel Switkin 提供。)
当特雷西回来后,布赖恩在团队中担任了新的角色:他成了“狗粮”经理,负责 Android 设备的分配。当手机从制造商那边进来时,布赖恩会给它们刻上独特的 ID。“那就是我的工作,尽可能快地刻印每一部手机,给成百上千需要拿到它们的人。如果发生泄密,我们可以追溯源头。但这对设备管理也是有好处的。”
激光刻印不仅仅限于测试设备。“杯子。眼镜。我们还尝试过火腿。火鸡。我们点燃了好几个火。我在那段时间学到了很多关于激光的知识。”
布赖恩喜欢那些完成工作所需的随机硬件。“有激光。有紫外线打印机。我记得在看着定制背壳 G1 打印时被晒伤了,因为每个背壳都会稍微变化一下,如果它们弯曲得太多,你就得调整打印机设置。我被晒伤了。就在室内。在没有窗户的楼区。”

布赖恩·琼斯的测试设备,一部预发布版 G1 手机,他用它来在刻印一批新设备之前先校准机器。
布赖恩负责设备分配的原因之一是,他的优先事项总是帮助产品。他不参与企业游戏。“决定谁拿到什么,是落在我肩上的事。我认为自己擅长的一件事就是不被人们的头衔、销售技巧或个性所左右。如果有人过来说,‘我需要这个东西’,我的第一个问题是,‘你为什么需要它,如果没有它,会有什么影响?’
“如果你是高管,有些影响是:我们不能做产品决策。但判断这些高管实际上如何发挥作用很重要。在早期,如果你是销售或广告部门的副总裁或高级副总裁,但这与 Android 无关,我根本不在乎你是谁。那与我的产品线无关。你和街上的任何人没什么区别。”
“我完全不介意告诉别人滚蛋,无论你是谁。如果我认识的团队成员,比如迈克·克莱隆(Mike Cleron),说‘我们的团队人手不够,我们需要一些设备,你能帮忙吗?’你们要什么就有什么。你们让产品得以实现,任何事都没有官僚障碍。我知道你们很重要,是核心组成部分,你们的请求绝对不是在抬高要求。”
最终,布赖恩成了每个需要 Android 设备的人的焦点。当设备到货时,他的桌子前会排着一条不间断的人龙。还有一波接一波的人会进大楼,找他和他的设备,并且问大楼里的人他在哪里。布鲁斯·盖伊(Bruce Gay),他坐在布赖恩旁边,在他的桌子上挂了一个牌子,上面写着“不是 Bjones”,就是为了搞清楚这一点。

布莱恩在 2007 年 12 月交付成果。这些要么是 Sooners,要么是正在向工程团队传递的非常早期的 G1 版本。(图片由布莱恩·斯威特兰德提供。)
第四十五章:Droid 做到了

“我做不到,但 Droid 做到了”
肌肉梗挑起了争斗
请处理受损的水果
—Mike Cleron
摩托罗拉 Droid 的市场成功是 Android 可能会成功的第一个信号。Android 一直在缓慢地获得采用和接受,但 Droid 是第一个大获成功的基于 Android 的产品,尤其是在美国。与之前的 Android 设备不同,Droid 的一个特点是它是第一个拥有真正营销活动的 Android 设备。Verizon 投入了 1 亿美元用于营销,并通过他们的“Droid 做到了”广告覆盖了无线电波。
Droid 于 2009 年 10 月 17 日发布,并于 11 月初正式发售,成为了商业上的成功,因为消费者开始更加认真地对待 Android 手机。同时,合作伙伴也开始更认真地看待 Android,最终推动了更多的产品(许多产品)的推出,进一步促进了基于 Android 的设备销量。
Michael Morrissey 记得发布时的影响:“我们很小,很拼命,不断推出所有这些操作系统更新,但我们觉得自己根本没能打动消费者。然后 Droid 有了一个大销售日。接着第二天也和第一天差不多,可能卖出了 65,000 部设备。但接下来我们就想,‘天啊,现在该怎么办?就这样吗?这些只是超级激动的早期采用者,它会消失吗?’但销量持续不错。我对数字的记忆不太准确,但大概是每天 30,000 部,持续了一段时间。一旦这种情况继续下去,Droid 真正成为了大热产品,我们就觉得‘我们现在有希望了’。”

摩托罗拉 Droid。滑开手机后,显示出一个硬件键盘。
但在 Android 团队内部,Droid 的开发情况却截然不同。起初,这是一个没人想要的产品。就在摩托罗拉接触 Google 合作开发这款设备的同时,HTC 也接触了 Google,想要共同开发 Passion 手机(最终发布为 Nexus One)。团队对 Passion 设备更为兴奋,因为它将是 Google 品牌的手机,意味着可以更好地掌控最终产品。
与此同时,Droid 在内部缺乏关注。Andy Rubin 起初甚至不想做这笔交易,原因包括运营商网络的细节。Rich Miner 回忆道:“Andy 不想做 CDMA(Verizon 的手机网络技术),因为我们在 T-Mo 上的第一批手机都是 GSM。我们(Rich 和 Hiroshi)必须把这件事推进到足够远的程度,基本上是违背 Andy 的意愿,以确保它有足够的动力,让我们清楚地意识到不能停止它。”
黄伟记得 Droid 和 Nexus One 之间的紧张关系:“Andy 更倾向于 Nexus One,因为它是他设想的产品。我认为它是一款更好的设备。”
与此同时,尼克萨斯一号将获得比 Droid 更多的联合品牌支持。Verizon 希望 Droid 成为一款 Verizon 设备,主要品牌包括 Verizon(运营商)和摩托罗拉(制造商)。而谷歌品牌并未出现在 Droid 上。
Droid 不仅在品牌和归属感上存在问题,它还……丑。Tom Moss 说:“它的边缘都是尖的,角落能把自己划伤。”
但营销能够起到作用,而 Droid 的营销活动正是做到了这一点。该活动利用了这款设备的独特之处,并将其潜在的弱点转化为强项,把它宣传成一款能够做更多事情的机器人设备,超越了竞争对手。显然,这个策略奏效了,美国市场上购买 Droid 的数量远超过了以前购买任何其他 Android 手机的人。Android 手机销量曾被竞争对手远远甩在后面,但到了 2010 年底,Android 的市场份额持续增长,完全超过了 iPhone 的销量。^(1)
Cédric Beust 在内部评论 Droid 与 Nexus 竞争时说道:“所以我们当时都有些得意洋洋,心里想着,‘是的,我们在做 Verizon,但更多是因为我们需要把钱放到桌面上。但真正重要的是 Nexus。’谷歌,或者说 Android,曾经傲慢地认为仅仅在我们的网站^(2)上卖手机就足够了。回想起来,真是太天真了。”
“然后我们看到了第一个电视广告,^(3) 这个广告给我们很多人留下了深刻印象。那真的是一个非常棒的广告。最终,Droid 手机大获成功,而我们的手机[尼克萨斯一号]表现不佳。我认为这对我们来说是一个非常谦逊的教训。我们开始意识到产品和营销的重要性,并且明白也许是时候传递接力棒了。我们一直被技术驱动。技术基础已经打好;现在需要让真正的市场接管。像 Verizon 这样的大公司将会把它带到下一个层次。”
Charles Mendis 表示同意。“他们的营销活动真的很有意思。”
“最初,特别是 Andy 和 Larry 想把这款 Droid 手机作为一款便宜的设备来卖。他们希望这款设备能够面向每个人。但 Verizon 却说,‘我们没有 iPhone,从品牌和营销的角度来看,我们不能把它作为一款便宜的设备卖。我们必须让人们觉得它和其他品牌一样好。’”
Verizon 为 Droid 制定了一个营销计划,并向团队展示了这个计划。Charles 说:“我觉得如果做一款更便宜的设备会更好。但 Verizon 做得很棒,他们抓住了重点。销售和市场反馈证明了这一点。”
Charles 认为,Droid 成功的另一个因素是公司内部对其的优先级。最初,Droid 和 Nexus One 打算同时发布。但最终做出决定先发布 Droid,再推出 Nexus One。Droid 于 2009 年 11 月发布,而 Nexus One 则在两个月后,即 1 月发布。
“将 Nexus One 推迟到第二年是 Droid 成功的另一个重要原因。之前,团队中有一个困惑:是应该修复 Nexus One 的 bug 还是 Droid 的 bug?Nexus One 是公司推出的设备。”
“Andy 最终做出了艰难的决定。他说‘Nexus One 之后发布,整个团队应该专注于 Droid’,这确实帮助我们把 Droid 作为一款设备成功推出。”
Droid 的硬件性能也起到了帮助作用。Charles Mendis 说:“在 G1 上,地图的一个最大问题是缓存会崩溃。我们会遇到‘内存不足’的异常,然后应用在使用过程中就死掉了。我们做了很多工作来绕过这个问题,但就是没有足够的 RAM 可用。当 Droid 发布时,我们实际上能够提供更好的体验。”
“在 G1 上,我们被迫在一个非常受限的环境中开发,而当 Droid 发布时,事情实际上运行得很好,因为我们是针对 G1 开发的。我觉得 G1 几乎像是一个 Beta 版本,迫使团队在非常紧张的限制下工作。Droid 上的体验相当不错,因为我们是为一个更紧凑的环境构建的。”
Droid 硬件的另一个重要方面是屏幕。Droid 是第一款屏幕尺寸(480 × 854)与原始 G1(320 × 480)不同的设备。此外,Droid 的像素密度也高于早期的设备(每英寸 265 像素,而早期设备为每英寸 180 像素)。这意味着开发者第一次能够看到以适应不同屏幕尺寸的方式构建应用程序的优势。
Droid 是 Android 的曲棍球棒^(4)时刻,Android 的采纳曲线迎来了急剧上升。Hiroshi 回忆道:“我记得大约在 Droid 发布的前后几天,我看到一篇文章,报道中采访了一位在 iPhone 和 iOS 上发布过应用并且已经在 Market 上发布的应用开发者。他们说,‘哇,我们已经注意到 Droid 了。’大约两天后,开发者说,‘我们在 Android 上的安装量已经大幅上升了。’那也是一个时刻,不仅是消费者的时刻,也是开发者的时刻,他们当时心里想,‘天啊,这个平台可能有前途。有人在买这些设备。’”
Droid 于十一月发布。几个月后,Dave Sparks 记起了他参加的一次员工会议。“那是在发布之后的几个月,大概是 1 月,我们刚开始看到增长的曲线。Eric Schmidt 召集了 Andy 团队的会议。我记得当时 Dianne 和 Mike Cleron 都在,基本上都是高层人物,Hiroshi 也在,显然。”
“Eric 看了看房间, said, '不要搞砸了。'”
第四十六章:三星与更多厂商
普遍认为,Droid 的发布标志着 Android 真正开始增长。但即便如此,Android 设备的销量在当时仍远远落后于 iOS,而其他手机制造商仍然占据着相当大的市场份额。
但到了 2010 年,局势真的开始发生变化,因为其他厂商也推出了自己的 Android 手机。于是,情况不再是人们只购买单一的 Verizon 手机,或是 Android 粉丝购买 G1 或 Nexus 手机,而是全球各地的人们购买各种不同的 Android 手机。
Hiroshi 谈到了 OEM 对生态系统的影响。“OEM 厂商需要制造设备。所以到了第二年,我们开始看到 Galaxy 系列的推出,然后它真的成为了一款主流产品。这是传统的合作伙伴关系,存在滞后效应。是的,有些滞后。最初的阶段总是有一些延迟,直到事情开始运转。这就是 G1 和 Droid 的意义,它们只是行业的启动阶段。然后所有的合作伙伴和 OEM 厂商都加入了,他们的产品开始发布,这时行业的飞跃就开始了。”
其中一个 OEM 厂商就是三星。
不可否认,三星对 Android 的积极影响;他们是 Android 设备最大的制造商,三星的Galaxy设备是 Android 手机中的旗舰品牌。即便是 Note 7 电池“爆炸”问题^(1),一个可能让小公司彻底崩溃的问题,也没有阻止人们在新设备推出时争相购买。
Tom Moss 在他居住在日本时签下了三星作为 Android 的合作伙伴。三星并不是最早推出 Android 的公司,他们花了一些时间才加入这个生态系统。但当他们加入时,他们全力以赴。
“我的工作不仅仅是达成交易。我的工作是帮助推动生态系统的建设。努力的一部分是确保生态系统中力量的平衡。那时,HTC 相对于其他厂商有着巨大的优势。第二款、第三款手机是 HTC 的。他们向运营商收取了非常高的 Android 手机价格,这不好,因为这将转嫁给消费者,导致更高的售价。”
“我们的目标是创造一种平衡的局面。我们确实需要一个活跃的 OEM 生态系统,彼此竞争。所以我的工作不仅仅是签约 OEM,而是帮助他们真正地利用这个机会。例如,在与三星的合作中,我选定他们作为我们在中国的首个发布手机。”虽然这款手机最终没有推出,但三星的手机最终还是在其他地方发布了。
Tom 谈到了公司采纳 Android 后所做的改变,包括为这些新的 Android 设备投入了大量的营销预算。“三星相信。当时其他 OEM 厂商几乎没有投入任何资金,而他们则在共营销上花费了资金,目的是打造 Galaxy 品牌。”
“在日本,我知道他们从卢卡斯影业授权了达斯·维德(Darth Vader),并让渡边谦(2)担任代言人。他们聘用了成千上万的工程师、设计师……一切都有。申宗均(3)押上了安卓智能手机的未来。他们是第一个真正投资于最后一公里的人,他们是第一个考虑在商店里设立三星销售代表来帮助推广的品牌,还在店内设立了小区域。他们的执行力堪称卓越。”
“技术和手机的进步后来才追赶上商业和销售的步伐。但实际上,这一切是由营销和销售策略主导的,正是这种策略让他们实现了跨越式发展,随后他们的设备越来越好。”
一旦技术到位,他们就迎战了智能手机市场的领导者:苹果。
“他们做了一场精彩的营销活动,直接将三星 Galaxy 与 iPhone 对比。他们有点在嘲笑 iPhone,人们都在想‘这家公司怎么这么傻,居然敢与 iPhone 抗衡?’但他们成功地将话题从 Android 与 iOS 之争转移到了 iPhone 与三星 Galaxy 的对比上。”
“即使在飞机上,你也会听到‘请关闭您的 iPhone 和三星 Galaxy’,而不是‘关闭您的 Android 设备’。”
第四十七章:曲线

随着三星和其他制造商开始在全球销售自家的安卓设备,随着 Droid 的发布,销量的上升迅速且持续增加。
当 Droid 在 2009 年末发布时,安卓平台在智能手机平台中处于较低的位置。到 2010 年底,也就是一年多后,安卓设备的销量已经超越了除了诺基亚的 Symbian OS 之外的所有平台,并且在第二年又超过了 Symbian。
与此同时,越来越多的人选择智能手机而不是功能手机,^(1) 即传统的低端(且体积较大)手机市场,许多人选择了安卓智能手机。

安卓系统在 2008 年末发布后,花了几年时间才在智能手机市场中崭露头角。^(2)

智能手机最终影响了功能手机市场,因为人们越来越倾向于选择这些更强大的设备,而不是那些功能有限的低端手机。^(3)
如果你扩大视野,考虑到所有计算设备,包括个人电脑,那么这些数字就更加有趣了。正如早期安卓创业团队在其推介中提到的一个要点,^(4) 自 2011 年以来,安卓设备的销量已经超越了个人电脑,并且自 2015 年以来,它们的销量是个人电脑的四倍以上。^(5)
乍一看,这个对比似乎让人困惑;个人电脑(各类台式机和笔记本)几十年来一直是现代生活的必需品。但世界上许多人把个人电脑视为奢侈品,而非必需品;他们购买的第一台计算设备是智能手机。智能手机与个人电脑不同,已经成为了必需品;它们满足了人们的各种需求(如通信、导航、娱乐、商务等),同时价格足够亲民,使得以前无法承担电脑的人也能够购买智能手机。智能手机也具有个人化特点,而“个人电脑”却并非如此;个人电脑通常是家庭共享设备,而大多数智能手机只有一个人使用,这使得智能手机的潜在市场远远大于个人电脑的市场。
这些趋势在随后的几年里持续发展。到 2021 年 5 月,全球活跃的安卓设备已经超过了三十亿部。(6)(7)
第四十八章:团队
我们一直为此感到骄傲——即使背后有苹果的阴影——我们很快。这个团队的速度是我前所未见的,无论是以前还是以后。
——Joe Onorato
从一开始,Android 团队就由具备正确技能和动力的人组成,他们能够构建所需的内容。创建一个完整的平台,以及 Android 所需的应用、服务和基础设施,是一项巨大的工作,并要求那些能够迅速投入并使事情运作的人付出艰苦的努力。
这不是一个大团队……但却是一个合适的团队。
正确的经验
大多数团队成员都有完全符合要求的经验,使得他们能够迅速投入工作。曾在 Be、Danger、PalmSource、WebTV 和微软等公司参与过相关平台和移动项目的经验,赋予他们在正确领域的技术基础,使他们能够应对 Android 所提出的类似问题。
正确的态度
随着接近 1.0 版本发布,Android 团队的规模有所增长,但在首次发布时,团队人数仅有大约 100 人。这意味着每个人都有足够的工作任务来发布产品。但大家做了必要的工作来推动进展,包括个人负责大型功能领域,并跨多个领域工作,无论哪里需要帮助。再加上那个早期的创业环境推动每个人拼命工作,团队能够从零开始编写 Android,交付一个强大的平台和设备,及时在初生的智能手机行业中占有一席之地。
正确的规模
团队规模小意味着每个人都必须非常努力地工作才能完成项目,但这也意味着他们的工作效率更高。
Ficus 在 1.0 发布多年后,开始领导 Play Store 团队时与 Brian Swetland 交谈:“他问我团队有多大。我告诉他 300 人。他的眼睛瞪大了,‘300 人,你可以做一个新的 Android!’”
“我说‘不行,300 人不行——你需要 20 个人。’那个更大的团队依赖于那些自然而然达成共识的个体所建立的代码和实践。在最初的阶段,所有的沟通和协调……如果你从一个大团队开始,你就会把所有时间都花在争论上。”
正确的领导力
伟大的团队得益于伟大的领导力,帮助每个人凝聚力量并共同向前推进。领导力的一个方面是让 Android 在 Google 这个大母舰内部像一个创业公司一样运作。另一个方面是由一个人做出决策,而不是一个小组。
San Mehat 说:“就像苹果一样,拥有那种富有远见的混蛋类型的人真的很有帮助。就是那一个人。不是一个委员会。不是五个人。就是一个人,像是‘我就是要这样做,这就是我要的样子,其他的我不在乎。’”
“让一个人处于决策的最高位置,使得团队和产品不断朝着目标前进。这是在做出决策,即使它不是正确的决定,但至少是为了推动进程。你如果不前进,就无法指引方向。”
第四十九章:决策,决策
一个优秀的团队做出好的决策。坚实的技术和商业决策帮助 Android 成功发布并实现增长,使其能够在制造商、开发者和用户的支持下实现潜力。
技术——获得粉丝的功能
Android 的大部分技术只是任何智能手机所需的基础技术:具备数据和无线功能的设备,以及像浏览器、电子邮件、地图和消息应用这样的标准应用。这些功能并不是 Android 增长的关键因素;它们更像是平台要有的勾选项,只有具备了这些,平台才能具备相关性。
但其他一些技术是 Android 独有的,这帮助 Android 建立了一个忠实的开发者和用户群体。这些功能从一开始就被内置于平台中,使 Android 与其他智能手机平台区分开来。
-
通知 Android 的通知系统帮助将整个系统联结在一起,因为应用程序与底层系统协作,将用户希望了解的信息传递给他们。
-
多任务 允许用户通过像“返回”和“最近使用”按钮这样的 UI 元素轻松快速地在应用程序之间切换,预示着移动计算的新动态,人们不断使用多个应用来完成任务。
-
安全性 从一开始,团队就意识到移动应用与桌面应用根本不同,因此构建了一个将应用程序彼此隔离的系统。安全性随着时间的推移变得越来越重要,但 Android 从一开始就提供了基础,甚至深入到内核和硬件的最低层。
-
大小很重要 团队使得应用能够适应不同的屏幕尺寸和密度,这在支持各种设备和尺寸的应用方面至关重要,确保应用无论在哪种设备上都能良好运行。
工具——创建应用生态系统
在 iPhone 和 Android 问世之前,确实存在移动设备的第三方应用程序。但应用并不是人们购买手机的真正原因,也没有主导用户在设备上的使用时间。相反,手机自带了处理大部分需求的内置应用:可以打电话、查看电子邮件、发送消息,也许还可以浏览网页(在有限的范围内)。
但是,一旦人们开始使用智能手机,他们能够做的事情变得更多,需求也远超设备公司在自己应用中能提供的内容。因此,虽然 Google 提供的 Gmail、地图、浏览器和消息应用在早期的 Android 系统中非常重要,但更重要的是 Android 打开了外部开发者的大门。Android 允许开发者编写并提供自己的应用程序,帮助创造一个丰富的生态系统,使用户能够做更多的事情,而不仅仅依赖 Google 提供的应用。
启动这个应用生态系统对平台至关重要;任何如今试图进入市场却没有丰富应用选择的平台都没有机会。团队为开发者提供了丰富的工具箱,支持这些应用以及整个应用生态系统的存在。
-
编程语言 选择 Java 编程语言使得新加入的 Android 开发者能够将现有技能迁移到这个新平台上。
-
API 从一开始,Android 就被编写成一个面向所有开发者的平台,而不仅仅是为了 Android 团队。为这些开发者提供公开 API,以访问核心系统功能,对实现强大的应用至关重要。
-
仅仅有 SDK API 就足以使应用开发成为可能……但却相当困难。通过增加文档、IDE 和一系列专为程序员设计的工具,Android 应用开发变得对于急于创建自己应用的广大开发者群体来说变得可能。
-
Android Market 创建一个集中式平台,让开发者销售他们的应用,用户则能找到大量且不断增长的应用集,这为今天我们所使用的庞大应用生态系统提供了起步。
商业—创建设备生态系统
从一开始,Android 就被设计为一个开放平台,供其他公司用来打造自己的产品,而不仅仅是一个用于制造 Google 手机的系统。几个关键的决策和举措使得 Android 能够在业界广泛推广。
-
开源 在 Android 之前,设备制造商唯一的选择要么是自己构建平台,要么是支付高额费用许可一个平台,或者是从现有但不完整的解决方案中拼凑出一个。Android 为迫切需要的平台提供了一个强大、免费且开放的选择。
-
开放手机联盟 将合作伙伴公司聚集在一起,组成 OHA,提供了一个关于 Android 对整个生态系统需求的统一愿景。最初甚至没有 Android 用户,更别说设备了,所以让所有这些竞争的利益和公司共同支持这个共享愿景,对于建立他们所期望的未来至关重要。
-
兼容性 使 Android 在多样化生态系统中正常运行的关键因素之一是实现的兼容性,确保开发者能够编写在所有设备上都能运行的应用,而不是为了众多可用设备而重写应用。为了解决这个问题,Android 团队提供了兼容性测试套件(CTS),供制造商确保每一款新设备上都提供兼容的实现。
-
合作伙伴关系 与各类合作伙伴建立关系,并将他们纳入安卓社区是至关重要的。提供一个平台是一回事,但制造商需要帮助,以确保这个平台能在他们的设备上运行良好,从而为安卓建立成功所需的动力。安卓团队与合作伙伴紧密合作,确保平台能够在新设备上运行良好,建立了一个设备供应链,推出了来自全球各地制造商的安卓手机市场。
收购——在坚实的基础上构建
当安卓还是一个初创公司时,他们面临着一个选择:继续独立发展,利用已经获得的风险资金,还是加入谷歌。他们选择了加入谷歌,决定认为在谷歌这样的大公司中,他们更有机会实现安卓的愿景,而单靠自己则无法做到这一点。
安卓能在谷歌内部开发,毫无疑问是其成功增长的重要因素。一方面,谷歌财力雄厚,资金更加充裕,包括在某些情况下购买技术而非从头开始开发。但安卓的成就不仅仅归功于有了谷歌的资金和资源。毕竟,在同一时期,许多其他大公司也未能在移动领域取得类似的成功。
安卓在谷歌的一大优势就是自主性。将团队与公司其他部分保持分离,给予他们初创公司的活力,这种活力是他们认为安卓在早期阶段推出首个产品时所需要的。同时,成为谷歌的一部分也让安卓在与合作伙伴的谈判中拥有了更多的杠杆,而这作为一个真正的初创公司是无法获得的。
与此同时,谷歌拥有安卓在成长过程中所需要的恰当技术基础设施。不仅谷歌的服务团队有足够的经验将谷歌应用与后端服务器连接起来,而且他们还依赖一个可以根据需求扩展的基础设施。一个能够处理 YouTube 极高下载需求的公司,也能应对安卓用户群体日益增长的 OTA 更新需求。
第五十章:时机^(1)
这是正确的产品,正确的时间。
—凯里·克拉克
我们正好处在正确的地方,正确的时间。
—迈克·克勒龙
部分原因是处在正确的地方,正确的时间。
—迪尔克·道赫提
这是在正确的地方,正确的时间做了正确的事。
—迈克·弗莱明
正确的产品,在正确的时间。
—瑞安·PC·吉布森
我们处在正确的地方,正确的时间。
—罗曼·盖
这与架构无关,而是关于处在正确的地方,正确的时间。
—黛安娜·哈克博恩
它发生在正确的地方,正确的时间。
—埃德·海尔
正确的事,正确的时间。
—史蒂夫·霍罗维茨
我们所有人都需要承认,这其中有一部分是处在正确的地方,正确的时间。
—菲库斯·柯克帕特里克
这是正确的地方,正确的时间。
—广濑智司
Android 在正确的时间出现在了那里。
—埃文·米拉
正确的地方,正确的时间。
—里奇·迈纳
正是时候组建一个智能手机操作系统。
—尼克·佩利
机会:就是在正确的地点,正确的时间。正是这种机会的存在。
—大卫·特纳
最大的原因跟时机有关。我们正好处在正确的地方,正确的时间。
—杰夫·雅克西克
时机至关重要。这对喜剧来说是真的,对生活来说也是真的,对 Android 的成功来说同样如此。对于 Android 来说,它的成功与其成为一个有趣的移动平台(那时有好几个这样的平台)和成为一个如今已在全球超过 30 亿台设备上运行的操作系统之间,差距就在于时机。
Android 时机的各个方面都很重要:团队能够多快推出 1.0 版本并交付更新,何时硬件足够可用且足够快以适应这种新设备形态,等等。但最重要的时机因素可以用一个词来总结:竞争。
竞争与合作
在 iPhone 发布后,制造商们急切需要推出自家的触摸屏产品,以便在不断发展的智能手机市场中竞争。鉴于 iPhone 的封闭生态系统,这些公司只能独自打造一个具有竞争力的系统,但没有公司处于一个好的位置去做到这一点。与此同时,Android 已经在开发一个平台,旨在支持不同种类的设备和需求,包括例如触摸屏的支持。
时机对那些公司与 Android 合作并利用这个开源平台创造自己的智能手机设备起到了正确的作用。
移动硬件
时机也对当时硬件能力产生了积极影响。CPU、GPU、内存和显示技术的融合使得更强大的智能手机成为可能。硬件能力的提升不仅带来了新型手机,还带来了一个全新的计算硬件细分市场,能够摆脱旧 PC 世界中固守的平台厂商的束缚。
招聘
时间把握还对原始团队的组建产生了影响。Android 在一个核心操作系统团队(来自 PalmSource、Danger 和 Microsoft 等公司)可用且渴望共同承担新项目的时刻进行了人员招聘。这些人同时加入的事实意味着,Android 在一个拥有相关经验且已经有过合作经验的团队的推动下启动,这些团队成员不需要花时间去建立团队动态,他们只是直接开始工作。
执行
时间把握的最终部分是,团队能够足够迅速地利用他们所获得的机会。首先,团队在 iPhone 发布时,已经能够将核心 Android 平台建设到一个合理的阶段,因此当时它几乎已经准备好供那些需要快速推出竞争方案的制造商使用。此外,团队能够根据触摸屏的新现实做出调整,成功地将 1.0 和 G1 推向市场,领先于其他可行的解决方案。
如果没有使智能手机得以实现的硬件能力的独特组合,也没有 iPhone 对一个正在苦苦寻找与新设备竞争方法的行业产生的独特影响,Android 可能无法找到立足点,最终只能成为许多失败品中的一员,沉寂于移动设备历史的街头。但相反,Android 能够在合适的时机成为一个可行的替代品,使全球制造商能够推出自己的智能手机,促成了我们今天所知道的 Android 生态系统。
第五十一章:成功!我们还在这里!

我们达到了 20 亿活跃用户,我猜这算是一种“我们做到了”的表现。但天啊,竞争:它永无止境。它是无情的。我们每天都在竞争。
就是感觉从来没有结束过。这就是我为什么还在这里的原因。
—广濑宏
这本书的最初目的是尝试回答这个问题:“为什么 Android 能够成功?”
但“成功”并不是最合适的词,甚至不是最准确的概念。在任何项目中,成功从来都不是保证的,无论在任何时刻看起来有多么光鲜亮丽。在科技领域尤其如此,因为硬件、软件、时尚、消费者兴趣,或者其他成千上万的因素的变化,都可能让一个看似成功的产品几乎在一夜之间陷入过时的深渊。这个领域的变化如此之快,以至于永远不会有“我们成功了!”的感觉,而是带着一点紧张的“我们还在这里!”,或者甚至带着怀疑的“我们还在这里?”同时回头看一看,看看谁在你背后,追赶得有多快。
对于 Android 来说,这个平台在过去几年里获得了足够的制造商、运营商、开发者和用户的支持,使其能够继续存在并不断改进。在高科技领域,这已经算是相当不错的成绩了。
第五十二章:行话
这本书从来不是为那些喜欢所有技术细节的工程师而写的技术书籍。相反,它是一本面向所有对商业和技术的迅猛崛起,以及背后努力的人们感兴趣的读者的书。
但是,当这些人编写代码并创造出带来这些结果的高度技术性内容时,很难避免偶尔会陷入技术细节的困扰。所以,当我解释,比如 Ficus Kirkpatrick 喜欢在系统的低层工作,或者 Brian Swetland 曾在 Danger 和 Android 上工作过内核,或者 Be 和 PalmSource 的工程师们为软件开发者创造了一个平台和 API 时,使用一些术语是有必要的,尽管这些术语可能会让非工程师的听众感到困惑或迷失。
为了尽量减少技术性噪音,我把许多相关的解释压缩到了这个附录中。希望这一简短的部分能够帮助解释重要的术语,更重要的是,解释系统中不同部分之间是如何相互关联的。
首先,系统概述
在我的行业中,讨论平台软件时,通常会画出我们称之为“层状图”的白板图,这个图显示了系统中各个组件之间的关系。这个示意图通常展示了从硬件到各个组件的层级结构。在图的顶部,我们看到用户交互的部分,而在底部,我们看到直接与硬件通信的组件。中间的所有部分是由工程师编写的软件层,目的是将用户的高层操作(例如,点击按钮)传递到硬件(例如,显示按钮的按下状态、启动应用程序、启动核弹等)。
这是一个(非常简化的)Android 操作系统示意图:

这里其实并没有什么特别针对 Android 的内容;这是一种典型的操作系统视图。Android 显然有一些独特的元素,这些元素在其他地方有解释。但总体而言,Android 平台与大多数其他操作系统相似。
让我们从上到下看一下这个示意图,讨论这些部分是什么,它们如何协同工作。
应用
Android 上的应用是用户的主要入口点。用户从应用图标启动应用,点击按钮、列表以及应用中的其他组件,点击应用中的链接以启动其他应用,等等。这基本上是用户所处的世界,直接与应用进行交互,而所有平台功能的访问则是间接的,通过这些应用暴露的接口来实现。
请注意,系统提供的主屏幕、导航栏、状态栏和锁屏等功能都被视为应用程序。即使它们是由平台提供的(无论是 Android 本身,还是某些情况下由像三星这样的制造商提供的系统应用程序),它们仍然只是应用程序。
API
应用程序编程接口(APIs)是平台中应用程序与之交互的功能模块。平台 API 是平台中公开的函数、变量及其他代码片段。例如,如果应用程序需要计算平方根,它们可能会调用平台提供的平方根 API 函数。或者,如果应用程序想要向用户显示一个按钮,它们可能会使用按钮 API 来处理按钮的功能和视觉效果。
API 是平台的冰山一角。虽然 Android 中有成千上万的 API,但它们其实只是平台功能的入口点,其中大多数功能嵌入在实现这些 API 的代码中。所以,举个例子,应用程序可能通过调用几个 API 函数来创建一个按钮,但在幕后,平台会做很多工作来处理按钮涉及的所有细节(包括如何显示按钮、如何处理点击事件以及如何绘制按钮的标签文本)。
框架
框架是处理所有通过公共 API 暴露功能的大层次系统软件。也就是说,框架既负责 API,也负责这些 API 的实现。在前面的示例中,这里就是按钮功能所在的地方,当然还有其他部分。框架涵盖了平台能够做的所有事情,比如位置服务、数据存储、电话服务、图形、用户界面,简而言之,几乎所有内容。Android 的 UI 工具包是框架功能的一个子集,专门针对用户界面 API 及其实现。
系统
上图中的系统部分表示正在运行的软件,它不能被应用程序直接访问,但它负责设备的整体功能。例如,在 Android 中,窗口管理器负责将应用程序显示在各自的窗口中,并在不同的应用程序启动时进行窗口切换。还有一个服务在运行,它通过杀死那些最近未被使用的应用程序来处理低内存情况,以便为最近使用的应用程序腾出所需的内存。所有这些操作间接地为用户执行。
系统调用公共 API 来实现各种必要的框架功能,但系统也可能直接调用框架中的函数(这就是为什么在图中它显示在 API 层旁边,而不是位于其上方)。
内核
内核,以及它的设备驱动程序,是运行在设备上的最低层软件。它处理设备的基本功能,是整个系统所需要的。例如,每个应用程序运行在一个 进程 中;管理设备上运行的多个进程(将它们相互隔离,并为它们分配 CPU 运行时间)是内核的职责。内核还负责加载和执行系统上的驱动程序。我们目前讨论的所有软件都适用于任何设备,但驱动程序是特定于某些硬件的。例如,要接收按钮上的点击,设备中的某个硬件能够将触摸屏上的触摸转换为触摸发生的位置信息。内核中的驱动程序完成这个工作,将硬件特定的数据转化为事件,然后将这些事件发送到框架中进行处理。同样,设备可能有用于存储、传感器、显示、相机等硬件的驱动程序。内核在设备启动时加载这些驱动程序,并在需要时通过驱动程序与硬件进行通信。
平台
最后,我使用 平台 这个术语来包含除应用程序外的所有内容。这是一个非常通用的术语,我广泛地用它来指代 Android 为应用开发者和用户提供的一切。Android 的平台软件包括所有为开发者编写应用程序提供功能的内容,以及设备所需的所有内容,用以展示基本的 UI 和功能。因此,当我谈论 Android 平台团队时,基本上指的是除了应用程序以外,负责上述所有内容的团队:包括负责内核、框架、系统软件和 API 的工程师。
其他技术术语
除了前面图表中便利地呈现的所有内容之外,书中还使用了一些其他技术术语,也值得解释。我相信我可能会遗漏一些。如果网络上有某种“搜索引擎”功能,读者可以轻松查找我不小心忘记提到的术语,那该多好啊……
Changelist
Changelist (CL) 指的是修复 bug、实现新功能、更新文档等所需的代码更改。一个 CL 可以是简单的一行修复,也可以是数千行代码,来实现一大堆新的 API 和功能。同行开发者更喜欢前者,因为一行代码容易审查和批准。对于那些依赖团队审查 10,000 行 CL 的开发者来说,运气不佳,因为大家都忙于交付自己的修复和功能。
Changelist 显然是一个主要由 Google 工程团队使用的术语。其他软件系统使用类似 补丁 或 PR(拉取请求)这样的术语来表示相同的意思。
模拟器
仿真器是一个模拟硬件设备的软件程序。开发者使用仿真器(特别是 Android 仿真器)来简化在他们用于编写应用程序的主机计算机上运行和测试程序的过程。与每次重新编译程序时都需要将其下载到物理设备并可能面临延迟不同,开发者可以直接在强大的桌面计算机上运行虚拟设备。
仿真器和模拟器之间存在差异;仿真器实际上模拟了真实设备上发生的一切,包括 CPU 和其运行的指令。模拟器通常是一个更简单(且通常更快速)的程序,因为它并不模拟设备上的所有内容,而是仅仅模拟足够的部分,使其基本上像设备一样运行。模拟器足以测试程序的基本功能,但可能会忽略一些重要细节(如硬件传感器的工作方式),因此开发者最好使用仿真器或真实设备来验证实际功能。Android 在早期有一个模拟器,但最终停止了对其的维护,转而仅保留了仿真器。
IDE
IDE(集成开发环境)是一套程序员用于编写、构建、运行、调试和测试应用程序的工具。这包括像文本编辑器这样的工具——通常了解程序员所使用的编程语言,并具备格式化和高亮显示该语言编写的代码的快捷方式,以及其他如代码补全和链接等功能——还有用于构建应用程序的编译器。例如,Android Studio(Android 团队为开发者提供的 IDE)包括一套庞大且不断增长的工具,其中包括各种编辑器(用于 Java、XML 和 C/C++),用于将代码构建为 Android 应用的编译器,一个用于在设备上逐步执行程序的调试器,以及其他分析性能、监控内存使用和构建 UI 资源的特定工具。
Java ME/J2ME
Java ME(或在 Android 开发早期阶段的 J2ME,^(1))是 Java 平台微型版(Java Platform, Micro Edition)的缩写,是早期移动设备的一个软件平台。Java ME 使用 Java 编程语言,并提供了应用程序开发者所需的功能,用于为这些设备编写应用。
J2ME 在移动领域承诺了开发者迫切需要的一项功能:一个通用平台,使他们能够为许多不同的设备编写应用程序,而不必为截然不同的硬件重新调整应用。
然而,与桌面或服务器版本的 Java 不同,Java ME 有多种版本,称为配置文件,这意味着任何特定实现的 Java ME 在设备上的功能未必与另一设备相同,因此 Java ME 开发者最终仍需处理设备多样性的问题。
OEM
OEM(原始设备制造商)是指制造实际硬件的公司。
面向对象编程:类、字段和方法
用于编写 Android 平台和 Android 应用程序的软件,采用了名为面向对象编程(OOP)的方法。大多数流行的现代语言也使用类似的方法,包括 Java、C++、Kotlin 等。在 OOP 系统中,有一些称为类的功能模块,提供一套特定功能的 API。例如,Android 有一个 String 类,用于执行文本字符串的操作。
每个类可能包含一组字段或属性,用于保存值。例如,String 对象可能保存一个文本字符串的值,例如 "I want a sandwich."
每个类还可能包含一组方法或函数,对该类(以及可能对其他类)执行操作。例如,Android 的 String 类有一个名为 toUpperCase() 的方法,正如其名称所示,它将返回一个大写字母的字符串。所以,之前的三明治字符串,如果调用 toUpperCase(),将返回值 "I WANT A SANDWICH."
类及其各种方法和字段可以捆绑在一起创建一个库。该库中的类、字段和方法代表该库的 API,应用程序(或其他库)可以从它们的代码中调用这些 API,执行库所提供的操作。
SDK
一个SDK(软件开发工具包)包含了程序员编写特定平台程序所需的组件。它包括程序员可以调用的平台功能的 API 以及实现这些 API 的库。通过使用 SDK,程序员可以编写应用程序。然后使用工具(通常随 SDK 一起提供),他们可以构建应用程序(将其编译成设备可理解的格式)。最后,他们可以在与编译后应用程序兼容的设备(或模拟器)上运行和调试程序。
工具包
工具包在含义和使用上与框架、库和 API 有重叠。通常,工具包指的是专门用于用户界面(UI)组件的框架。在 Android 中,工具包与UI 工具包同义,指的是 Android 用户界面技术的 API 和实现。它被视为整体 Android 框架的一部分,特别是该框架中处理大部分视觉方面的子集。
视图
所有 UI 平台都有某种 UI 元素的概念,比如按钮、复选框、滑块、文本或包含所有这些对象的容器。但是,它们对这些元素的称呼在不同平台之间有所不同,因此很难判断开发者在谈论哪个平台,因为他们使用了不同的术语。Java 的 Swing 工具包称这些为组件,一些平台称其为元素或小部件。在 Android 中,UI 元素被称为视图(Views),这一名称来源于所有这些元素继承自的类(View)。视图的容器(包括其他容器)被称为 ViewGroup。最后,视图层次结构,如其名称所示,是指视图和 ViewGroup 的层次结构,从顶级父视图 ViewGroup 开始,包含它的子视图,再到其中包含的任何 ViewGroup 及其子视图,依此类推。
第五十三章:相关内容
在写这本书的过程中,我读了很多书籍、文章、文档、网站以及任何与 Android、其他移动技术或技术历史相关的内容。以下是我觉得比较有用且值得记住的资源。
关于 Android 的资料
“Android 的(更新版)历史”,Ars Technica,作者:Ron Amadeo(arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/):这是一系列分章节的文章,涵盖了 Android 从 1.0 开始的每次发布,详细说明了应用、设备和用户界面上的可见变化。最棒的部分是所有的屏幕截图,因为现在已经找不到这些截图了(即便你有一部老设备,它可能也无法连接到原来的服务了)。
“Android 回顾”,由 Romain Guy 和 Chet Haase 做的演讲(youtu.be/xOccHEgIvwY):我和我的朋友 Romain 在不同的开发者活动上多次做了这个演讲,讨论了我们如何开发某些功能以及从团队内部看待这些内容的情况。
Android 开发者幕后,由 Chet Haase、Romain Guy 和 Tor Norbye 主持的播客(adbackstage.libsyn.com/):这是我与我的朋友和 Android 同事 Romain 和 Tor 一起主持的播客。我提到它是因为,虽然它主要是为开发者制作的播客,但其中有一些集数是更多地讲述 Android 的历史。特别是,我们曾与 Ficus Kirkpatrick(第 56 集)、Mathias Agopian(第 74 集)、Dave Burke(第 107 集)和 Dan Bornstein(第 156 集)一起聊过一些我在书中提到的过去的日子。写这本书过程中,我最喜欢的部分是与团队成员的对话;这些播客提供了我们一些对话的片段。
现代操作系统,第四版,作者:Andrew S. Tanenbaum 和 Herbert Bos(Pearson,2014):对于那些觉得关于 Android 操作系统内部技术深度不足的人,我推荐阅读这本关于操作系统设计的教材,并深入学习第 10.8 章关于 Android 的内容。那一章由 Dianne Hackborn 撰写,详细介绍了如 Binder 和 Linux 扩展等内容,我觉得这些内容已经超出了这本书原本就有些过于技术化和冗长的范围。
移动技术案例研究
有几本优秀的书籍讲述了那些在这个时期未能取得成功的手机平台和移动公司历史。我特别喜欢以下两本:
失去信号:黑莓的非凡崛起与辉煌衰落背后的故事,作者:Jacquie McNish 和 Sean Silcoff(Flatiron Books,2015)。
《埃洛普行动:诺基亚手机的最后岁月》,梅丽娜·萨尔米宁与佩卡·尼卡宁著:原版芬兰书籍《Operaatio Elop》从未翻译成英文,但通过一项众筹翻译的努力,最终将其以 PDF 等格式翻译成英文,并可在线访问,网址为asokan.org/operation-elop/。
硅谷科技历史
关于科技历史,也有许多精彩的书籍和纪录片,其中包括这些我非常喜欢的:
《革命中的硅谷:Mac 的传奇故事》,安迪·赫兹菲尔德著(O’Reilly Media,2004):这是一本非常棒的书,帮助人们了解硅谷历史上最具标志性的故事之一是如何诞生的。它同样提供了对参与该项目的团队与人物的精彩洞察。
史蒂夫·乔布斯,沃尔特·艾萨克森著(Simon & Schuster,2011):我喜欢这本书,不仅因为它生动地描绘了乔布斯先生的形象,更因为它讲述了硅谷和高科技的历史,甚至更重要的是,它带给了我对这些历史的深刻了解。
《通用魔力》(纪录片),由莎拉·凯鲁伊什与马特·莫德执导:这部电影详细展现了一个公司文化与愿景的幕后故事,这家公司本可能成为移动计算领域的早期成功者,只可惜它们至少提前了 10 年。
第一部分
起初
一开始肯定没有那种不可避免的感觉。有很多原因解释为什么安卓不应该像现在这样成功。这是那种我认为如果你想再次让它发生,你也做不到的事情。这里面有些魔力。
—埃文·米勒

第二部分
构建平台
Android 平台的构建是从底层开始的,这是必然的。
就像在没有地基和下面五十层楼的情况下,想要在摩天大楼顶部建造顶层公寓是很困难的,构建 Android 应用程序时,如果没有底层操作系统内核、图形系统、框架、UI 工具包、API 和其他基础层,也是非常困难的。因为没有什么比走进你的新顶层公寓然后直接摔倒到街道上更糟糕的了。

第三部分
Android 团队
从 Android 团队加入 Google 的那一刻起,他们就有自己独特的工作方式。团队领导层尽力保持这种方式。

第四部分
发布
从 iPhone 发布的那一刻起,到 Android 1.0 发布后的第一年,所有的重点都集中在发布上。无论是发布不同版本的 SDK 软件、对从 1.0 版本起发布的平台进行迭代,还是推出种类越来越多的设备,团队都在不断努力,争分夺秒,确保平台能够及时推出,覆盖越来越广泛的受众。

第五部分
为什么它成功了
我认为,简而言之,这就是安卓成功的原因:每个人都在一起。没有这种合作伙伴关系的做法,我们绝对无法达到安卓所取得的规模和成功。
—Ficus Kirkpatrick

你读了很多页^(1)才来到这里。恭喜你!在这里,我将所有内容整合在一起,回答这个问题:安卓是如何成功的?考虑到所有可能导致失败的因素,而这些因素确实让许多其他公司和平台在同一时期试图在智能手机领域竞争时失败了,为什么是安卓呢?就像任何成功的项目一样,背后有许多因素,但这一切都始于团队。
附录
附录
-
一个可以被移除而不会危及系统的内脏器官,
-
并且系统几乎完全不会察觉到。
-
它的存在仅仅是为了在必须移除时可能引发致命的危险。
-
除此之外,它可以安全地忽略。


浙公网安备 33010602011771号