跨平台移动开发工具:PhoneGap与Titanium全方位比拼

我在面向开发者的各项活动和大会上经常被问及一个问题:Titanium与PhoneGap相比到底怎样。我想,看来有必要抽点时间,从宏观层面解释每一项技术是如何工作的,并且评估这两项技术彼此相比怎样。

跨平台移动开发工具:PhoneGap与Titanium全方位比拼_第1张图片

从宏观层面来看,PhoneGap和Titanium似乎很相似。它们都提供了跨平台移动开发工具。两者还在一定程度上都需要使用JavaScript和Web技术。Titanium和PhoneGap都是采用宽松许可证的开源软件(Titanium Mobile SDK是采用Apache 2.0许可证发布的;PhoneGap采用了类似的许可方式,PhoneGap又被称为是Apache软件基金会管理的项目“Cordova”的一个“发行版”)。

但是两者的相似之处其实仅限于此。虽然这两项技术的目的都是能够实现跨平台的移动开发,但是解决这个问题的一套理念和方法却没有多少共同之处。此外,从赞助公司的角度来看——PhoneGap的赞助公司是Adobe,Titanium的赞助公司是Appcelerator,每个项目背后的商业目的大不一样。我将从自己的视角,在下文尽量详细地描述技术、理念和商业模式方面的这些差异。

另外,要是你之前还没有了解,我要声明一下:本人长期以来是Appcelerator的代码捐献者和雇员。话虽如此,我还是尽量立足于客观的技术事实,从技术和理论层面对这两项技术作一番评述。如果你觉得我阐述的观点哪里与事实不符或者误人子弟,请留言告诉我,我会酌情更新这篇博文。

我会先从宏观层面描述这两项技术是如何工作的,还会描述这两项技术如何用额外的原生功能来扩展。就每项技术而言,我还会总结它们所选择的跨平台开发方法存在的主要优缺点。技术上的差异很快就会一目了然,但是我做了这些概述和比较后,还会描述这两个平台在理念上和战略上有什么差异、它们将何去何从。

不妨先来介绍一下PhoneGap及其是如何工作的。

PhoneGap想实现什么样的目的?

PhoneGap的目的是,让基于HTML的Web应用程序可以作为原生应用程序来部署和安装。PhoneGap Web应用程序由原生应用程序外壳来加以包装,可以通过面向多个平台的原生应用程序商店来加以安装。此外,PhoneGap力求提供Web应用程序通常无法使用的常用的原生API(应用编程接口)集,比如之前在浏览器中还没有提供的基本摄像头访问、设备中的联系人资料和传感器。

从更宏观的层面来看,PhoneGap可以看作是新兴的万维网联盟(W3C)设备API标准的开路先锋,因为它们试图现在就让Web开发者感受和领略未来。如今,没有哪个平台将Web应用程序视作一等公民,不过Mozilla大有希望的Boot To Gecko平台有机会改变这种情况。在优先通过API访问Web应用程序方面,微软的Windows 8也正在取得进展,值得关注。但是PhoneGap的目的是,现在就为Web应用程序获得一小部分的此类权利。

PhoneGap的最终用户工作流、工具和接口

想开发PhoneGap应用程序,开发者就要在本地目录中创建HTML、CSS和JavaScript文件,其方式酷似开发静态网站。实际上,一些PhoneGap开发者提到了这款工具的额外好处:自己大多数时候可以在桌面Web浏览器中进行开发,根本不需要原生工具链(toolchain)。

想在原生仿真器/模拟器上运行PhoneGap应用程序,开发者就得为自己想要支持的每一个原生平台创建一个项目,并且使用Xcode、Eclipse或所需的任何原生工具链,配置该项目的“web root”目录,然后使用该工具来运行项目。具体步骤在每个平台各自的入门指南中均有概述。符号链接常常用来跨多个原生项目,把“www”文件夹传送到一个共同的目录位置。

把原生包装的PhoneGap应用程序安装到设备上需要相似的工作流。不过,为了补充这个过程,并且缓解本地安装原生软件开发工具包(SDK)的需要,最近被Adobe收购的Nitobi建立了一项名为PhoneGap Build的服务,该服务可以在云端创建易于安装的应用程序。支持PhoneGap编译部署的功能最近已集成到了Adobe的Dreamweaver工具中。

与PhoneGap结合使用的工具是标准的Web开发工具,比如Firebug、Web Inspector和你所选择的文本编辑器。还出现了一种用于远程调试的新兴工具,名为Weinre;这款工具如今得到了更广泛的应用。总的来说,你开发原生应用程序这个事实在开发过程中基本上是抽象的。

PhoneGap是如何工作的?

正如我们之前提到的那样,PhoneGap应用程序是一种“原生包装”的Web应用程序。不妨探讨一下Web应用程序是如何加以“包装”的。

许多原生移动开发SDK提供了Web浏览器窗口组件(“Web视图”),作为用户界面框架(比如iOS和Android)的一部分。在纯原生应用程序中,Web视图控件用来显示来自远程服务器的HTML内容,或者显示以某种方式与原生应用程序一起封装的本地HTML内容。由PhoneGap创建的原生“包装器”(wrapper)应用程序把前后端开发者的HTML页面装入到这其中一个Web视图控件,并且在应用程序启动后,将随后出现的HTML作为用户界面来显示。

如果JavaScript文件包括在Web视图装入的页面中,该代码就在页面上以正常方式来评估。不过,创建Web视图的原生应用程序能够以不同的方式(取决于具体平台),与Web视图里面运行的JavaScript代码进行异步通信。这项技术在PhoneGap架构中通常被称为“桥接”(bridge)技术——在Titanium中,“桥接”又有着稍有不同的含义,本文后面会有介绍。

PhoneGap充分利用该技术在Web视图里面创建JavaScriptAPI,能够以异步方式将消息发送到包装器应用程序中的原生代码,以及接收来自包装器应用程序中原生代码的消息。每个平台实现桥接层的方式各有不同;但在iOS平台上,当你需要联系人列表时,你的原生方法调用就会进入到通过桥接发送的请求队列。随后,PhoneGap会创建iframe,iframe会装入统一资源标识符方案(“gap://”),原生应用程序经配置后处理该统一资源标识符方案;这时候所有的队列命令将被执行。通过在Web视图的环境下评估JavaScript串,就能回过头来从原生代码联系到Web视图。

PhoneGap的工作方式绝不止这些,但是通过实现桥接技术完成从Web视图到原生代码的消息传递却是这项技术的核心部分,这让本地Web应用程序得以调用原生代码。

扩展PhoneGap

为PhoneGap编写原生扩展需要你:

  1. 为扩展编写JavaScript接口,它将使用PhoneGap的API,将发送到原生代码的消息排成队列。 

  2. 以某种方式将你的扩展登记到原生项目——在iOS上,这一步在Cordova.plist文件中完成。

  3. 编写原生代码,PhoneGap将从Web视图发送请求至原生代码,并实现所需的任何原生代码。

大致上来说,开发者可以参与到驱动核心PhoneGap原生API的同一个异步消息传递系统.

PhoneGap方法的优点

据本人估计,PhoneGap架构方面的主要优点是,它非常小巧、简单。它只做自己擅长的工作。PhoneGap团队有意为基于Web浏览器的应用程序只实现最基本的原生API。由于原生API集非常小,因而把PhoneGap移植到许多不同的环境来得比较容易。基本上来说,支持Web视图或Web运行时环境的任何原生平台都可以是一种PhoneGap平台。

PhoneGap中的非可视原生扩展也非常简单。说到登记原生代码、接收来自Web视图的消息,这方面的要求也非常低。因而可以迅速开发出简单的原生扩展。在我看来,这种插入式架构还得到了很好地落实。

另外还有这个优点:原生API和原生应用程序开发对前后端开发者来说几乎完全是抽象的。凡是能编写HTML、CSS、甚至一小段JavaScript代码的人都能用原生应用程序来包装网页,并将其作为原生应用程序来分发。使用PhoneGap把网页包装成原生应用程序方面的准入门槛极低。

PhoneGap方法的缺点

PhoneGap应用程序中用户界面的质量会不一样,取决于Web视图和平台上渲染引擎的质量。iOS平台上基于Webkit的渲染引擎很强大,并且提供了最佳性能。AndroidWeb视图可以用,但是存在一些明显的局限性。在其他平台上,Web视图的性能可能成问题,这要看操作系统的版本。

还有Web开发者始终不得不处理的常见的跨浏览器问题。用户界面需要采用渐进式增强、媒体查询和种种办法,才能在多个平台上依然可以使用。现在许多移动平台采用Webkit,这有所帮助;但是即便在基于Webkit的环境中,仍存在很大的差异。

移动浏览器一直在变得越来越好,这将有助于缓解那些问题。但着手处理浏览器中原生用户界面质量的用户界面性能绝非易事——Sencha雇用了一大批的Web编程专家,让这些专职人员专门解决这个问题。即使如此,在大多数平台上,在如今的大多数浏览器中,根本不可能达到原生用户界面质量的用户界面性能和响应能力,哪怕使用像Sencha Touch这么高级的框架。不过,浏览器是不是已经“足够好”?这取决于你的需求和感受,但是毫无疑问它不如原生用户界面来得好。有时候要差得多,这取决于实际的浏览器。

PhoneGap还无法用原生用户界面来加以扩展。前后端开发者的应用程序本身驻留在Web视图里面,用户界面由HTML加以渲染。你可以把消息传递到原生代码,并创建在Web视图之上或邻近Web视图的原生用户界面,但是很难或不可能把动态的、基于文档对象模型(DOM)的HTML用户界面与原生用户界面组件集成起来。Appcelerator会想出办法——我们试图及早把原生用户界面与DOM元素联系起来,但由于结果无法预测,而且质量不够好,因而需要放弃这方面的工作。

力求“最基本”是把双刃剑,它还有另一面。默认情况下,提供给PhoneGap应用程序的原生API非常少,这使得平台集成很有限。现在有各种各样的插件,它们用来堵住其中一些漏洞;但是在我看来,它们的质量和维护水平参差不一。不过,这方面的情况很可能会继续得到改进——PhoneGap有一个强大的社区。

我们不久会更深入地探讨PhoneGap的理念方面,但是先来探讨一下Titanium的同样这些技术方面。

Titanium想实现什么样的目的?

Titanium Mobile的目的是,为移动开发提供一种高级的、跨平台的JavaScript运行时环境和API(今天,我们支持iOS、Android和浏览器,很快会支持黑莓10,最终会支持Windows Phone。)Titanium与MacRuby/Hot Cocoa、PHP或node.js的共同之处实际上多于它与PhoneGap、Adobe AIR、Corona或Rhomobile的共同之处。Titanium基于移动开发方面的两个现实:

•有一套核心的移动开发API,它们可以跨平台进行规范。这些方面的重点应放在代码重用上。 

•有针对特定平台的API、用户界面公约以及功能特性,开发者在针对该特定平台从事开发时应该采用。应该有针对特定平台的代码,以便这些用例提供最佳的用户体验。

由于这些原因,Titanium并不是想“编写一次、到处运行”。我们认为,开发者应该使用面向多个平台的优秀的、用户体验增强特性。我们认为,必要时,原生应用程序应充分利用熟悉的、高性能的原生用户界面窗口组件。不过我们认为,原生应用程序开发者没必要为了绘制长方形或提出HTTP请求而要学会针对特定平台的API。

Titanium试图借助统一的JavaScript API、针对特定平台的功能特性以及原生性能,实现代码重用,从而满足用户的预期要求。你在编写Titanium应用程序时,其实是用JavaScript来编写原生应用程序。Titanium应该被视作是一种用来编写原生应用程序的框架,而不是对你针对的实际平台予以抽象化。

Titanium的最终用户工作流、工具和接口

想用Titanium来开发原生应用程序,开发者就需要安装面向iOS和Android的原生工具链。不过,这些工具安装完毕后,开发者通常只能与TitaniumSDK的脚本接口(如今基于Python)进行交互。这一步可以直接通过命令行来完成,也可以通过我们基于Eclipse的集成开发环境(IDE):Titanium Studio来完成,后一种方式比较常见。

使用Titanium工具集,你可以创建含有配置文件和本地化文件的应用程序项目目录,以及含有图像、资产和为了运行应用程序而编写的JavaScript源代码的目录。在默认情况下,你不用编辑HTML和CSS文件,除非你想创建同时含有原生用户界面和基于HTML的用户界面的混合型应用程序。Titanium应用程序可以、而且常常的确采用“混合型”(原生和Web)用户界面,比如Facebook的原生应用程序。这样一来,开发者实际上可以实现PhoneGap和Titanium,但是这不在本文的讨论范围之内。

借助该工具链,你的应用程序使用面向目标平台的实际仿真器/模拟器来运行。TitaniumStudio还提供了逐步调试、代码完成及其他IDE级别的特性。

安装到设备上进行测试也通常使用我们的编译系统来完成。在Studio中,我们提供了一个向导界面,以配置任何代码签名依赖关系,然后处理将应用程序部署到连接设备上的任务。还可以使用原生工具链来部署或包装你的应用程序,如果你喜欢这么做的话。

等到将你的应用程序发布到应用程序商店时,我们的编译系统将为你处理创建最终应用程序包的任务。借助原生工具链,这一步在开发者的机器上本地完成。上传过程对纯原生应用程序开发者来说一样。

开发Titanium应用程序时,底层的工具链大多数是抽象的。它们是开发所必不可少的,但是很少要求前后端开发者直接使用它们。不过,开发原生应用程序这并不抽象。用户界面是用跨平台组件和针对特定平台的组件共同开发而成的,你的应用程序应该处理这些事务:后台服务、本地通知、应用程序标记、配置、活动/目的(在Android平台上)……所有这些都通过Titanium JavaScript API来提供。

Titanium是如何工作的?

Titanium应用程序后台发生的事情相当复杂。但大致上来说,在运行时,你的应用程序包括三个主要组件:JavaScript源代码(内嵌在Java或Objective-C文件中,作为编码字符串来编译);用原生编程语言针对特定平台实现的TitaniumAPI;以及用来在运行时评估代码的JavaScript解释器(默认解释器是V8,或面向Android的Rhino解释器,或面向iOS的JavaScriptCore解释器)。当然在浏览器中除外,这时将使用内置的JavaScript引擎。
   你的应用程序启动后,JavaScript执行环境由原生代码来创建,你的应用程序源代码进行评估。被插入到你应用程序JavaScript运行时环境的是我们所说的“代理”对象——这基本上是在原生代码中有配对对象的JavaScript对象。我们常常俗称为Titanium应用程序中的“JavaScript地带”(JavaScript land)和“原生地带”(native land),因为它们在某种程度上彼此并行。代理对象在JavaScript地带和原生地带中同时存在,充当两者之间的“桥梁”。

在你的JavaScript代码中,当你针对全局Titanium或Ti对象调用函数时,比如var b = Ti.UI.createButton({title:'Poke Me'});,这将调用一种会创建原生用户界面对象的原生方法,并创建一个“代理”对象(b),向JavaScript提供关于底层原生用户界面对象的属性和方法。

用户界面组件(视图代理)可以在层次体系上加以安排,以创建复杂的用户界面。为非可视API(比如文件系统输入/输出或数据库访问)呈现界面的代理对象用原生代码软来执行,并以同步方式将结果返回给JavaScript;如果是网络访问等API,则以异步方式返回结果。

但愿这有助于直接消除Titanium方面的两个常见的误解——第一个误解是,Titanium从来不需要使用Web视图组件。开发者可以把Web视图创建成原生用户界面窗口组件,但是Web视图并不用来评估Titanium源代码。第二个误解是,JavaScript代码在Titanium中并不交叉编译成Objective-C或Java。你的JavaScript源代码在运行时加以评估。

扩展Titanium

Titanium可以用原生代码,由非可视功能和用户界面功能来扩展。通过用原生代码来实现代理接口及/或视图代理接口,开发者就能为由JavaScript提供的Titanium应用程序创建新的原生功能。我们为使用iOS和Android平台的模块开发者提供了用来创建Titanium自有内部接口的同一接口。

Titanium方法的优点

由于Titanium的目的是为跨平台的原生移动开发提供一种更高级的API,所以你可以直接访问一系列广泛的原生特性和功能,从用户界面组件、插座接口到通知系统集成。Titanium的目的是,将Titanium应用程序和纯原生应用程序之间在功能方面的差异缩小到几乎为零。我们可能从来不直接支持整个平台的API,但是我们希望能涵盖90%最常见的用例,并且提供一个平台,以便有需要的人可以添加剩余10%的用例。

由于Titanium可以用插入到与应用程序其余部分一样的视图层次体系的可视组件来扩展,你最终能够在底层原生平台上实现任何可能的用户界面。需要使用特殊的原生代码,让表格视图(TableView)以60fps的速度滚动?你能做到这一点。想无缝地集成游戏的OpenGL绘制曲面,同时用JavaScript保留运行循环的逻辑?你能做到这一点。你可以把这些用户界面扩展直接集成到用核心Titanium API编写的应用程序中。

使用常用的用户界面窗口组件时,Titanium应用程序的外观和感觉也是这种平台的一个优点。不用进行可视仿真(或通过应用CSS,或者使用OpenGL或Flash渲染用户界面窗口组件)。当你创建NavigationGroup时,它得到iOS上的实际UINavigationController的支持。动画和行为与原生应用程序用户预期的相一致,因为你使用同样的用户界面控件。

由于Titanium通过JavaScript提供了一种高级的原生编程API,为用过基于ECMAScript的语言(这门语言拥有众多开发者)的任何人大大降低了原生编程方面的准入门槛。正由于Titanium,阿特伍德定律(Atwood’s Law)依然适用。该定律是指:凡是可以用JavaScript编写的应用程序,最终都会用JavaScript来编写(详见)。

Titanium方法的缺点

Titanium API的范围使得添加新平台有难度——在一种新的原生平台上实现Titanium API是项艰巨任务。正由于如此,Titanium平台只出现在目前被认为最重要的移动平台上:iOS、Android和Web。

我们的移动Web浏览器支持还没有达到可以投放市场的质量——我们在继续致力于改进我们的用户界面窗口组件集的性能和感觉上,同时完善核心Titanium API的实现。

由于Titanium提供的抽象层很庞大,我们自己的内部框架仍存在API实现未达到最佳标准的问题。在一些情况下,一些用户界面组件还无法做到性能与原生用户界面组件一样好,比如布局高度定制化的非常庞大的表格视图。优化核心的用户界面组件对我们团队来说仍是首要的技术任务。由于我们日渐克服缺陷、硬件日臻完善,我们看到这不再是个问题。我们还发现,许多情况下需要运用信息架构,对庞大数据集而言更是如此。

另外由于Titanium平台的宏伟目标,扩展Titanium并非易事。想有效地集成一种新的原生控件或API,深入了解Titanium的架构和环境必不可少。开发者体验、API文档和面向模块开发者的总体指南。因我们最新的2.0版本而有了大幅改进,但仍是我们关注的一个方面。

理念方面的差异

至此,我希望PhoneGap和Titanium技术方面的差异已很明了。但是除了那些差异外,每个项目的目的和方向也不同。PhoneGap的既定目标是最终不复存在。如前所述,PhoneGap旨在成为实现设备方面新兴浏览器标准的主要手段。从理论上来说,一旦浏览器厂商实现了PhoneGap的特性,这个平台将再也没有必要。PhoneGap本身不想成为一种平台——它是把类似原生应用程序的功能添加到Web应用程序的一种插件(shim)。Web旨在成为这样的平台。

PhoneGap新的赞助公司Adobe对于Web作为一种平台日臻完善也有着非常浓厚的兴趣。近几个月来,Adobe一直在不遗余力地生产能够开发HTML 5/CSS 3 Web应用程序的工具。在我及其他许多人看来,由于标准Web技术不断发展,Adobe显然认为Flash的角色日渐式微。

就本质而言,Adobe是一家主攻工具的公司。平台其实是Adobe可用来销售工具的一个渠道。这个平台一度是Flash。而现在,除了Flash外,这个平台主要还是Web浏览器。我不知道PhoneGap在Adobe的产品路线图中到底扮演怎样的角色,但是从许多方面来看,它起到了与Flash相似的用途。PhoneGap试图建立一种抽象的运行时环境,能够实现跨平台部署。

如果Adobe能销售为Web进行开发的工具,Web又可以用来开发更多种类的应用程序,那么这对Adobe来说显然是一大胜利。顺便说一下,这很好——销售工具没什么不对。

不过值得一提的是,Adobe并不是Cordova项目的管理机构,如今PhoneGap基于该项目。这个项目归Apache软件基金会拥有和管理。这两个项目之间会产生怎样的相互影响仍需拭目以待;但是我的直觉认为,它们不会出现很大的分歧。我认为,这两个项目的目的在理念上仍会保持一致。

Appcelerator也对Web作为一种平台日臻完善抱有兴趣,并给予了支持。当Web作为一种应用程序平台变得更强大,大家都是赢家。区别在于,我们认为Web是其中一种出色的平台,具有独有的特性和一系列优缺点。我们并未指望Web成为唯一的移动应用程序平台。我们认为,iOS、Android、黑莓和WindowsPhone之类的平台继续颇具影响力,为用户们提供出色的体验。这种选择和竞争对消费者来说将是件好事,但是对开发者来说仍是个问题。

我们期望通过Titanium为开发者提供的是这样一种方式:借助单一代码库,同时涵盖Web平台和原生平台,同时保留该平台的用户所期望的特性、性能以及紧密的平台集成。我们期望为移动客户端开发建立一种持久不衰的平台,而服务和工具可以加快这个过程。我们不是一家主攻工具的公司——我们是一家平台公司,我们的成功将与使用我们平台的开发者的成功息息相关。随着时间的推移,我们希望打造一家开源平台公司,本着红帽及该领域其他巨头的精神。

哪种工具或方法适合你?就像软件开发领域的所有方面一样,这得看情况。没有什么万能的技术。不过但愿这番描述和比较会帮助你做出适合自己情形的选择。

原文地址:

http://developer.appcelerator.com/blog/2012/05/comparing-titanium-and-phonegap.html


你可能感兴趣的:(Cordova,比较,Titanium,PhoneGap)