最新版的移动 Web 开发框架 Dojo Mobile 1.7,是 Dojo Toolkit 的一个扩展。本文将使您了解如何从主干网址下载 Dojo 1.7,以及如何在您的应用程序中使用 Dojo Mobile。您还将探索它提供的各种小部件和组件,学习如何使用 PhoneGap 将 Web 应用程序包装在原生应用程序中。
简介
移动 Web 使用量正呈指数型增长。随着更多的人习惯于使用智能手机或其他移动设备浏览 Web,针对那些为了实现移动版本而进行优化的网站和 Web 应用程序的需求在增加。由于平台数量越来越多(iOS、Android、Blackberry OS、webOS、Windows Phone、Symbian、Bada 等),很难开发针对多个移动操作系统的原生应用程序。
因此,人们迫切需要开发移动 Web 应用程序的工具包。几个主要的 JavaScript 框架(Dojo、jQuery 和 Sencha)很快提供了完全感知触摸屏的框架。通过与 PhoneGap 等原生编译工具包相结合使用,这些框架可以为原生开发提供出色的替代方法。Web 开发人员可以使用他们已熟悉的语言和框架构建原生应用程序,然后相对容易地将这些应用程序部署到许多平台上。
在本文中,我们将了解 Dojo Mobile,它是 Dojo Toolkit 的扩展。我们会先研究移动 Web 与原生应用程序之间的区别,然后通过示例了解如何在应用程序中包含和使用 Dojo Mobile 小部件。还要了解如何使用 PhoneGap 构建原生应用程序。您可以 下载 本文中使用的源代码。
移动 Web 与原生应用程序
关于使用原生平台还是使用 Web 平台开发移动应用程序的争论可能会持续很长一段时间。这两种方法各有优缺点。在许多情况下,应该根据应用程序需求和个人偏好来选择。
为什么要编写原生应用程序而不是使用移动 Web ?表 1 总结了编写原生应用程序的一些优点和缺点。
- 代码更快,可以直接在设备的操作系统上运行,不需要中间的浏览器应用程序。
- 可以部署到应用程序商店中,这提供了简单且经济有效的分发模型。
- 原生 SDK 有许多设备特有的特性,通常有详细的文档说明和示例。
- 由于各个平台 SDK 中的编程语言和 API 存在一些差异,所以需要针对不同的设备要求完全分隔同一应用程序的各个版本。
- 通过应用程序商店部署原生应用程序通常需要第三方批准,这会显著降低将应用程序投放市场的速度(尤其在应用程序遭到拒绝的时候)。
- 发布更新(即使是很小的更新)需要经过批准过程,这让向用户交付关键的更新变得更困难。
表 2 总结了移动 Web 应用程序的优点和缺点。
- 只需编写一个应用程序,即可部署到多个平台。不需要为不同的设备编写不同的版本。
- 可以通过 Web 部署应用程序,不需要第三方应用程序商店。
- 您可以获得应用程序产生的所有收入(如果收费的话)。
- 对于通过 Web 分发的应用程序,如果通过浏览器使用它们,则无法像原生应用程序那样使用许多设备特性(相机、麦克风等),尽管这个限制以后可能会有所改变。
- 您需要提供用于分发应用程序的基础架构,这比使用应用程序商店更困难、成本更高。
- 因为应用程序在浏览器中运行,而不是通过操作系统执行,所以应用程序的运行速度不如相应的原生应用程序。
幸运的是,有一个折中方法可以同时提供移动 Web 和原生方式的优势。可以使用 PhoneGap 等平台将移动 Web 应用程序包装在原生包装器中,这提供了 JavaScript API,使您能够访问原生设备 API。还可以将 Web 应用程序作为原生应用程序部署到各个应用程序商店。有关的详细信息,请参阅 用 PhoneGap 进行原生部署。
Dojo Mobile 概述
Dojo Mobile 是 Dojo Toolkit 的扩展,它提供了一系列在移动设备(比如智能手机或平板电脑)上使用而优化的小部件或组件。这些组件基于相应的原生组件,为熟悉智能手机应用程序的用户提 供了熟悉的界面。可以使用主题定制这些组件,例如可以向 iOS 用户而不是 Android 用户提供不同的样式集。
Dojo Mobile 的使用方式与 Dijit 组件库类似。要想在应用程序中使用某种小部件,首先需要在应用程序的主 JavaScript 块中使用dojo.require加载相关的类。然后可以在应用程序中添加这种小部件,既可以使用带dojoType属性的常规 HTML 标记以声明的方式添加小部件,也可以使用 JavaScript 代码通过程序添加小部件。
Dojo Mobile 在 iOS、Android 和 BlackBerry OS 6 设备上表现很好,这主要是因为在这些平台上有 WebKit 浏览器。这一优势在提供了比较完善的 WebKit 浏览器的其他平台(比如 HP webOS 及其他设备)上也能发挥很好的效果。在非 WebKit 浏览器上,Dojo Mobile 应用程序会优雅地使用替代方法,它们甚至可以在老式的桌面浏览器中运行(包括 Microsoft® Internet Explorer)。在默认情况下,只提供了 CSS3 样式,但是,只需使用一行代码,就可以为非 WebKit 浏览器添加兼容性模块:
dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
Dojo Mobile 的关键特性包括:
- 由于使用 Dojo Mobile 解析器,实现了小部件的轻量加载。
- CSS3 动画和渐变,可以在高端 iOS 和 Android 设备上产生与原生应用程序相似的体验。
- 包含提供 iOS、Android 和 BlackBerry 外观的主题。
- 能够与非 CSS3 兼容的设备和浏览器进行兼容。
- 完全声明式的语法,便于学习。
- 一个庞大的 UI 小部件和组件套件,提供了针对移动友好的界面的丰富内容
下一节通过构建 “Hello, World” 应用程序解释如何开始使用 Dojo Mobile。
Dojo Mobile 1.7 入门
在编写本文时,Dojo 的最新的稳定版本是 1.6.1。要立即开始使用 Dojo Mobile 1.7,则需要从一个 Subversion 存储库中下载 Dojo Toolkit 最新的版本。svn 命令行工具通常已预先安装在 Mac OS X 和 Linux® 操作系统上。如果使用 Windows®,那么您可能需要先下载和安装这些工具。有关的更多信息,请访问 Subversion 站点。
假设您已经安装了 Subversion,并且正在使用基于命令行的工具,那么您可使用以下命令迁出最新的 Dojo 版本。该命令会下载完整的 Dojo Toolkit 源代码,所以预计会花一段时间。
svn checkout http://svn.dojotoolkit.org/src/view/anon/all/trunk dojo-toolkit-readonly
当完成迁出后,您将在一个名为 dojo-toolkit-readonly 的新目录中拥有 Dojo Toolkit 的完整源代码。将此目录复制或移动到您 Web 服务器上的一个位置,以便您能够在 HTML 文档中使用它。将它重命名为更短的名称,比如 dojo-toolkit,然后就可以开始使用 Dojo 了。
如果愿意的话,可以仅下载您想要的 Dojo Toolkit 部分。一些人发现首先下载完整版本,然后丢弃不需要的部分更容易一些。Dojo 的源代码没有压缩且比较大,所以不建议在生产应用程序中使用它。
清单 1 给出了 Dojo 应用程序的基本结构。Dojo Mobile 1.7 中新增了deviceTheme类,它将自动确定要为您使用的设备加载的准确主题。您无需检测用户的浏览器并提供相关的 CSS 文件。
当完成迁出后,您将在一个名为 dojo-toolkit-readonly 的新目录中拥有 Dojo Toolkit 的完整源代码。将此目录复制或移动到您 Web 服务器上的一个位置,以便您能够在 HTML 文档中使用它。将它重命名为更短的名称,比如 dojo-toolkit,然后就可以开始使用 Dojo 了。 如果愿意的话,可以仅下载您想要的 Dojo Toolkit 部分。一些人发现首先下载完整版本,然后丢弃不需要的部分更容易一些。Dojo 的源代码没有压缩且比较大,所以不建议在生产应用程序中使用它。请参阅 参考资料,了解有关创建自定义 Dojo 构建版本来提升 Dojo 应用程序性能的信息。
清单 1 给出了 Dojo 应用程序的基本结构。
<!doctype html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1 ,maximum-scale=1,minimum-scale=1,user-scalable=no"> <meta name="apple-mobie-web-app-capable" content="yes"> <title>My Dojo Mobile App</title> <script src="dojo-toolkit/dojo/dojo.js" djConfig="parseOnLoad: true"></script> <script> dojo.require("dojox.mobile.parser"); dojo.require("dojox.mobile"); dojo.require("dojox.mobile.compat"); dojo.require("dojox.mobile.deviceTheme"); </script> </head> <body> <!-- Dojo Widgets Go Here --> </body> </html>
如果将清单 1 中的代码保存到文件中,在 Web 浏览器中打开此文件,将会看到一个灰色背景,再没有任何内容。这没什么用,所以让我们在应用程序中添加一些内容。本文中的示例使用了非标准的 Dojo Mobile 类,所以需要用dojo.require加载它们。在dojo.require("dojox.mobile");行的后面,添加清单 2 所示的代码。
人工加载 Dojo Mobile 类
dojo.require("dojox.mobile.ScrollableView"); dojo.require("dojox.mobile.SwapView"); dojo.require("dojox.mobile.IconContainer"); dojo.require("dojox.mobile.Button"); dojo.require("dojox.mobile.SpinWheelDatePicker"); dojo.require("dojox.mobile.SpinWheelTimePicker");
现在,可以添加 "Hello World" 应用程序的主要代码。本文中的示例使用了 Dojo Mobile 的声明式语法,这意味着要使用带特殊 Dojo Mobile 属性的常规 HTML 标记,在运行时解析 Dojo Mobile 属性。在代码的<body>部分中,添加清单 3 中的代码。
<div dojoType="dojox.mobile.ScrollableView" selected="true"> <h1 dojoType="dojox.mobile.Heading" fixed="top">Hello, World!</h1> <h2 dojoType="dojox.mobile.RoundRectCategory">First Section</h2> <div dojoType="dojox.mobile.RoundRect"> This is a nice standard rounded rectangular label. </div> <h2 dojoType="dojox.mobile.RoundRectCategory">Second Section</h2> <ul dojoType="dojox.mobile.RoundRectList"> <li dojoType="dojox.mobile.ListItem">List Item 1</li> <li dojoType="dojox.mobile.ListItem">List Item 2</li> <li dojoType="dojox.mobile.ListItem">List Item 3</li> <li dojoType="dojox.mobile.ListItem">List Item 4</li> <li dojoType="dojox.mobile.ListItem">List Item 5</li> </ul> </div>
上述代码定义了一个ScrollableView,它构成主要的应用程序界面。标准的View类与ScrollableView类之间的主要差异是:标准的View使用标准的浏览器机制来滚动页面。ScrollableView类有自己的滚动机制,可以像原生应用程序一样固定应用程序中的页眉和页脚,滚动它们之间的内容。
在ScrollableView中有一个Heading,它是包含文本 “Hello, World” 的标题栏。通过在这个对象上设置属性fixed="top",Dojo Mobile 会将这个标题一直留在屏幕顶部,滚动它下面的其他内容。RoundRectCategory对象为圆形的列表或单一列表项定义了一个组标题。第一个类别后面是一个RoundRect框,其中包含一些静态文本。然后是另一个类别标题和RoundRectList对象,该对象包含一系列ListItem对象。最终结果应该像图 1 这样。
图 1. Hello World 应用程序
下一节将讨论可以在 Dojo Mobile 1.7 中使用各种小部件和组件。
小部件
Dojo Mobile 附带了许多小部件,它们是专门针对移动设备而设计和优化的。这些小部件包括布局组件(视图)、列表、导航栏、标签栏、按钮和表单。本节将介绍许多小部件的 作用并提供基本代码示例。本节中的屏幕图取自使用 iPhone 主题的 iOS 设备,如果使用 Android 主题,屏幕会有差异。
View
View是一个容器小部件,它占据设备屏幕上的所有可用空间。应用程序的页面可以包含多个View对象,但只有其中的一个对象在任何时候都处于活跃状态。用户通常可以使用工具栏按钮和标签栏按钮在不同的视图之间切换,在视图之间移动时,可以获得各种渐变效果。图 2 显示了一个空的View示例。
使用 Dojo 基本 SDK 中的dojox.mobile.View类创建View对象。不需要使用dojo.require加载它。在使用View对象时,可以使用 selected 属性决定是否在启动应用程序时显示这个视图(启动视图)。以声明方式创建以上 View 需要使用以下代码。
<div dojoType="dojox.mobile.View" selected="true"></div>
也可以使用 JavaScript 以程序方式创建View。清单 4 给出使用这种方法创建图 2 中的View的代码。
var myView = new dojox.mobile.View({ selected: true }, "myView"); myView.startup();
清单 4 假设在 HTML 中有一个块元素,其id属性值是myView。它在 DOM 中将一个View对象绑定到这个元素。
后面对小部件的讨论涉及如何仅以声明方式使用它们。关于如何用程序语法使用 Dojo Mobile 小部件的更多信息,请查阅 Dojo API。
ScrollableView
ScrollableView小部件与View小部件相似:被用作放置其他小部件的容器。主要区别是,对于ScrollableView,如果内容超过屏幕的高度,用户可以通过触摸屏幕并上下滚动内容(如果使用水平滚动,就是左右移动),而页眉和页脚对象保持不动。如果使用标准的View对象,会滚动整个屏幕,页眉和页脚不会留在固定的位置。图 3 显示了一个示例。
创建空的ScrollableView对象与创建空的View对象非常相似。创建空的ScrollableView的代码是:
<div dojoType="dojox.mobile.ScrollableView" selected="true"></div>
建议希望在视图中添加固定的页眉或页脚时使用ScrollableView,否则,应该使用常规的View类。
与常规的View类不同,基本类中不包含ScrollableView,所以需要使用dojo.require加载它。
SwapView(以前为FlippableView)
SwapView小部件以前名为FlippableView,在 Dojo Mobile 1.7 中已不推荐使用。SwapView可以创建一个容器对象,可以通过触碰屏幕左右边切换为其他SwapView对象。视图的次序取决于它们在代码中的次序。图 4 显示一个SwapView小部件。
如果希望创建一个包含两个视图的示例FlippableView,可以使用清单 5 中的代码。如果使用了 Dojo 1.7,则需要将FlippableView更改为SwapView。
<div dojoType="dojox.mobile.SwapView" selected="true">View 1</div> <div dojoType="dojox.mobile.SwapView">View 2</div>
基本类中不包含SwapView,需要使用dojo.require加载它。
Heading
Heading小部件可以创建导航栏,导航栏出现在应用程序的顶部。Heading对象通常包含一个标题。您还可以在导航栏中添加导航元素(比如 Back 按钮)或工具栏按钮,以便提供简便的应用程序导航。
如果在ScrollableView容器中使用Heading,Heading小部件会固定在应用程序的顶部,而应用程序的其余部分会滚动。这让用户一直可以使用导航元素。图 5 显示了一个Heading对象示例,该示例包括标题、Back 按钮和工具栏按钮。
清单 6 给出了创建图 5 中的Heading小部件的代码。
<h1 dojoType="dojox.mobile.Heading" label="My App" back="Back" moveTo="back"> <div dojoType="dojox.mobile.ToolBarButton" label="Edit" class="mblColorBlue" style="width:25px;float:right"> </div> </h1>
您可能会注意到,Back 按钮实际上是在Heading元素中定义的。back属性定义了应该在按钮中显示的文本。moveTo属性应该包含当用户按 Back 按钮时激活的View对象的 ID。还可以使用 transition 属性定义以这种方式导航到另一个视图时产生的渐变效果。默认设置是 slide,其他选项包括 fade、flip 和 none。
可以使用ToolBarButton小部件定义其他导航按钮。如果希望获得采用与左边的 Back 按钮样式不同的按钮,或者希望在右边显示按钮,只需在Heading元素中添加ToolBarButton对象。
RoundRect
RoundRect类可以创建简单的圆角容器,可以在其中放置静态 HTML 或其他 Dojo Mobile 小部件。图 6 显示了RoundRect小部件的示例。
要想创建图 6 中的RoundRect对象,可以使用清单 7 所示的语法。
<div dojoType="dojox.mobile.RoundRect" shadow="true"> This is a simple RoundRect object with some content in it. </div>
RoundRect类非常简单。它只接受一个属性shadow,默认情况下被设置为 false。这个属性只定义容器是否应有阴影。
RoundRectCategory和RoundRectList
在移动设备上显示数据时,列表非常重要。可以使用垂直的表格结构显示一系列列表项。可以使用列表项显示导航或其他信息。Dojo Mobile 允许创建两种列表,它们都有相关联的类别小部件。RoundRectList创建列表的两边有间隙,在第一个和最后一个列表项上有圆角。图 7 显示在 iPhone 上看到的RoundRectCategory和RoundRectList。
这个示例定义了一个RoundRectCategory,其中包含标签 “List Heading” 以及一个包含三个ListItem对象的RoundRectList对象。清单 8 给出创建这些小部件的代码。
<h2 dojoType="dojox.mobile.RoundRectCategory">List Heading</h2> <ul dojoType="dojox.mobile.RoundRectList"> <li dojoType="dojox.mobile.ListItem">List Item 1</li> <li dojoType="dojox.mobile.ListItem">List Item 2</li> <li dojoType="dojox.mobile.ListItem">List Item 3</li> </ul>
EdgeToEdgeCategory和EdgeToEdgeList
EdgeToEdgeList与RoundRectList很相似。可以采用完全相同的方式使用EdgeToEdgeList,但是它创建的列表会占据视图的整个宽度。图 8 给出一个示例。
EdgeToEdgeList的代码几乎与前一个示例完全相同,只是RoundRect的引用替换成了EdgeToEdge,参见清单 9。
<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">List Heading</h2> <ul dojoType="dojox.mobile.EdgeToEdgeList"> <li dojoType="dojox.mobile.ListItem">List Item 1</li> <li dojoType="dojox.mobile.ListItem">List Item 2</li> <li dojoType="dojox.mobile.ListItem">List Item 3</li> </ul>
通常使用上面的列表显示人名列表,人名一般按姓氏的第一个字母分组。
IconContainer
可以使用IconContainer小部件定义一系列图标,每当触碰图标时,都会打开一个单独的容器。IconItem对象可以从嵌套在自身中的容器(在同一视图上)中滑出,也可以把当前使用的View切换为具有特定 ID 的视图。图 9 显示一个包含三个图标的IconContainer。
使用清单 10 所示的代码创建上面的IconContainer。
<ul dojoType="dojox.mobile.IconContainer"> <li dojoType="dojox.mobile.IconItem" label="Icon 1" icon="appicon.png" moveTo="view1"></li> <li dojoType="dojox.mobile.IconItem" label="Icon 2" icon="appicon.png" moveTo="view2"></li> <li dojoType="dojox.mobile.IconItem" label="Icon 3" icon="appicon.png" moveTo="view3"></li> </ul>
in _base.js 中不包含IconContainer类,所以需要使用dojo.require加载它。但是,IconItem不是这样,所以不需要人工加载它,否则在运行应用程序时会出现错误。
还有更多关于这些小部件的详细信息,但它们超出了本文的讨论范围。请通过 参考资料 中的链接进一步了解 Dojo Mobile Showcase 和 API。
Button
可以使用Button类创建简单的按钮对象。然后,可以使用dojo.connect在这个小部件上创建处理 “click" 等事件的代码。图 10 给出一个示例。
创建这个按钮的代码很简单,参见清单 11。
<button dojoType="dojox.mobile.Button" class="mblBlueButton" style="width: 100px">Click me!</button>
可以使用 CSS 自行创建新的按钮风格,使用 class 属性把类名分配给按钮。如果使用过 Dojo Mobile 1.6,请注意 1.7 版本中对Button类进行的以下更改。
- 它不再包含在 _base.js 中,因此您需要使用dojo.require明确加载Button类(本文前面的示例就是这么做的)。
- 使用 class 属性把一个类名分配给按钮,而不是像以前一样使用btnClass属性。如果尝试在 1.7 版本中使用btnClass,您可能会发现按钮的外观与预期不符。
Switch
Switch对象是一个开关控件,可以在两个值之间切换对象的值。在默认情况下,该值是 ON 或 OFF。改变开关值的方法是,触碰希望切换到的值,或者将开关滑动到目标值。图 11 给出Switch小部件的示例,其中有两个开关:一个在 OFF 位置上,另一个在 ON 位置上。
下面的代码创建一个Switch对象。
<div dojoType="dojox.mobile.Switch" value="off"></div>
Switch小部件还接受另外两个属性leftLabel和rightLabel,它们分别定义在开和关状态下应显示的值。在默认情况下,标签是 ON 和 OFF。当改变Switch的值时,会触发onStateChanged事件。可以使用dojo.connect处理这个事件。
TabBar
TabBar小部件用于在触碰TabBarButton时激活或取消激活视图,从而将View对象换入或换出应用程序。TabBar小部件可以使用iconBase属性定义图像 sprite,在每个TabBarButton中显示不同的图标。当使用TabBar作为应用程序底部的导航组件时,这样做的效果很好,参见图 12。
还可以使用TabBar组件和segmentedControl的barType属性。这样创建的标签栏通常适合放在应用程序顶部的主Heading小部件下面。图 13 给出这种TabBar的示例。
清单 12 中显示了创建图 13 中的TabBar的代码。
<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl"> <li dojoType="dojox.mobile.TabBarButton" moveTo="view1" selected="true">Albums</li> <li dojoType="dojox.mobile.TabBarButton" moveTo="view2">Events</li> </ul>
您必须使用dojo.require明确加载TabBar类,否则会获得一些令人费解的错误消息。但是,TabBarButton类不需要明确加载。
TabBarButton类有许多配置选项,可以用它们定制按钮的外观。可以指定图标的位置、应该使用的图标、改变视图时使用的渐变、完成渐变时触发的回调函数等。有关的更多信息,请参见 Dojo API。
Carousel
Carousel小部件是 Dojo 1.7 中新增的部件,可用于创建旋转式图像库,您可以滑动手指或使用导航控制小部件来旋转它。图 14 显示了Carousel小部件的一个示例。
要使用Carousel组件,必须定义一个ItemFileReadStore对象作为存储器,其中包含一系列图像。例如,清单 13 给出了在您的 JavaScript 代码块中定义的一个 JSON 对象。
var json = { items: [ {src:"images/pic1.jpg"}, {src:"images/pic2.jpg"}, {src:"images/pic3.jpg"}, {src:"images/pic4.jpg"}, {src:"images/pic5.jpg"}, {src:"images/pic6.jpg"}, {src:"images/pic7.jpg"}, {src:"images/pic8.jpg"}, {src:"images/pic9.jpg"}, {src:"images/pic10.jpg"} ] };
然后可以定义一个ItemFileReadStore对象和 carousel 本身,如清单 14 所示。
<span jsId="store1" dojoType="dojo.data.ItemFileReadStore" data= "json"></span> <div dojoType="dojox.mobile.Carousel" height="280px" store="store1" numVisible="1" title="Photo Gallery"></div>
清单 14 中的代码可用来创建一个类似于 图 14 的相册Carousel。numVisible属性定义了一次显示多少幅图像。
SpinWheel
SpinWheel组件是一个小部件,可使用它从旋转界面中选择值。iPhone 用户应对自旋式日期选取器组件和类似的控件很熟悉。SpinWheel组件可用于创建自定义的转轮。或者可以分别使用SpinWheelDatePicker或SpinWheelTimePicker创建日期和时间选取器。图 15 显示了这两个小部件。
创建SpinWheelDatePicker和SpinWheelTimePicker很简单。这两个小部件默认情况下均未包含在基础框架中,所以必须明确加载相关的类dojox.mobile.SpinWheelDatePicker和dojox.mobile.SpinWheelTimePicker。没有比实际创建选取器更简单的方法了。清单 15 中的代码将分别使用 ID spin1 和 spin2 创建一个日期选取器和时间选取器。
<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div> <div id="spin2" dojoType="dojox.mobile.SpinWheelTimePicker"></div>
当然,除非可以读取每个转轮上的值,否则SpinWheels没有多大用处。要获取日期选取器中第一个转轮的当前值,只需使用 slots 属性和getValue函数,如下所示。
dijit.byId("spin1").slots[0].getValue()
可使用SpinWheel和SpinWheelslot 类创建一个自定义主题。轮槽 (wheel slot) 可包含文本和图像,所以它们是高度可定制的。有关的更多信息,请参阅 Dojo Mobile 开发人员测试。
用 PhoneGap 进行原生部署
通过移动 Web 部署应用程序变得越来越流行。随着移动浏览器的改进和 HTML5 的发展,移动 Web 会成为移动应用程序的更强大的分发方式。但是,在许多情况下,人们希望将应用程序以原生方式部署到相关平台的应用程序商店。现在,不必使用每个平台的原生 SDK 开发应用程序的不同版本,而是可以使用 PhoneGap 将移动 Web 应用程序包装在原生包中。
PhoneGap 是一个开源项目,可以在任何应用程序中免费使用,无论应用程序采用什么分发模型(免费、商业、开源或混合式许可证)。PhoneGap 本身采用的是 MIT 和 BSD 开源许可证。您可以选择最适合自己的许可证。
PhoneGap 包含为六种平台构建原生应用程序的 SDK:iOS、Android、Blackberry、webOS、Windows Mobile 和 Symbian。开始使用 PhoneGap 的步骤因平台而异。这一节会介绍如何将它部署到 iOS 上。
我们来创建一个非常基础的 Dojo 应用程序,使用 PhoneGap 在 iOS 设备上以原生方式运行。为了构建原生的 iOS 应用程序,需要包含 OS X 10.6 Snow Leopard 和 Xcode 的 Mac 计算机。可以从 Apple 的 Developer Center 或 Mac App Store 下载 Xcode。一定要下载 iOS SDK,否则无法构建 iOS 应用程序。
假设已经安装了 Xcode 和 iOS SDK:
- 下载 PhoneGap 的最新版本(一个 zip 文件)。
- 提取并打开这个文件中的 iOS 目录。您将会看到名为 PhoneGapLibInstaller.pkg 的包。
- 启动 PhoneGapLibInstaller.pkg,将 PhoneGap 安装到 Xcode 中。
- 安装程序运行结束时,启动 Xcode 并创建一个新项目。
- 在左边的项目类型组中,选择 User Templates 组下面的 PhoneGap(参见图 16),然后在右边选择 PhoneGap-based Application。
- 单击 Choose,指定项目的名称(这个示例命名为 “HelloNative”)。
在 Xcode 中的 Groups & Files 部分,通常在窗口的左侧展开 “www” 文件夹。在该文件夹中,需要放入在本文开头从 Subversion 迁出 Dojo 1.7 时创建的 dojo-toolkit 目录。在开发应用程序过程中,通常会构建一个自定义的 Dojo 包并仅包含所需的文件。
在 Dojo 1.7 中不能删除 dijit 子目录(像 Dojo 1.6 中一样),因为最新版本中有一些 Dijit 类的依赖关系。如果希望精减应用程序的大小,则应该创建一个自定义的 Dojo 构建版本,这可以确保您不会删除任何依赖关系。
如果尝试将 dojo-toolkit 文件夹拖放到 www 文件夹中,您会发现这不起作用。您需要在 Finder 中双击 www 文件夹来打开它,然后将 dojo-toolkit 文件夹复制到 www 文件夹中。该文件夹可能不会立即显示在 Xcode 中,所以可以折叠并展开 www 文件夹来刷新视图。借助 PhoneGap 中包含的 Dojo 1.7,您可以继续构建应用程序本身。
打开 index.html 文件。该文件中的代码应该类似于清单 16。
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width; initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- iPad/iPhone specific css below, add after your main css > <link rel="stylesheet" media="only screen and (max-device-width: 1024px)" href="ipad.css" type="text/css" /> <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" /> --> <!-- If you application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here --> <script type="text/javascript" charset="utf-8" src="phonegap.0.9.6.min.js"> </script> <script type="text/javascript" charset="utf-8"> // If you want to prevent dragging, uncomment this section /* function preventBehavior(e) { e.preventDefault(); }; document.addEventListener("touchmove", preventBehavior, false); */ /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch. See http://iphonedevelopertips.com/cocoa/launching-your -own-application-via-a-custom-url-scheme.html for more details -jm */ /* function handleOpenURL(url) { // TODO: do something with the url passed in. } */ function onBodyLoad() { document.addEventListener("deviceready",onDeviceReady,false); } /* When this function is called, PhoneGap has been initialized and is ready to roll */ /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch. See http://iphonedevelopertips.com/cocoa/launching-your- own-application-via-a-custom-url-scheme.html for more details -jm */ function onDeviceReady() { // do your thing! navigator.notification.alert("PhoneGap is working") } </script> </head> <body onload="onBodyLoad()"> <h1>Hey, it's PhoneGap!</h1> <p>Don't know how to get started? Check out <em><a href="http://github.com/phonegap/phonegap-start">PhoneGap Start</a> </em> </body> </html>
现在,我们要构建与 “Hello, World” 应用程序功能相同的原生应用程序。第一步是包含 Dojo 本身。在 index.html 中找到以下行:
<script type="text/javascript" charset="utf-8" src="phonegap.0.9.6.js"></script>
在这一行下面,添加清单 17 中的以下代码。
<link rel="stylesheet" href="dojo-toolkit/dojox/mobile/themes/iphone/iphone.css"> <script src="dojo-toolkit/dojo/dojo.js" djConfig="parseOnLoad: true"></script>
清单 17 中的代码会根据需要加载 Dojo 的 CSS 和 JavaScript 文件。在此代码下方,应该有一个内联的<script>代码块。在这里添加清单 18 中的代码,以加载相关的 Dojo 类。
dojo.require("dojox.mobile.parser"); dojo.require("dojox.mobile"); dojo.require("dojox.mobile.ScrollableView");
清单 18 中的代码会加载 Dojo Mobile 解析器和基类,以及ScrollableView容器小部件。在本例中无需兼容层,因为目标设备 iOS 肯定会使用 WebKit。
找到 JavaScript 函数onDeviceReady。在注释 “do your thing!” 下方,删除以下代码,确保不会在每次运行应用程序时获得一个警告对话框:
navigator.notification.alert("PhoneGap is working")
最后需要加载的代码(如清单 19 所示)是小部件本身。将以下代码添加到 index.html 中的开始和结束<body>元素之间,删除 PhoneGap 添加的默认代码。
<div dojoType="dojox.mobile.ScrollableView" selected="true"> <h1 dojoType="dojox.mobile.Heading" fixed="top">Hello, World!</h1> <h2 dojoType="dojox.mobile.RoundRectCategory">First Section</h2> <div dojoType="dojox.mobile.RoundRect"> This is a nice standard rounded rectangular label. </div> <h2 dojoType="dojox.mobile.RoundRectCategory">Second Section</h2> <ul dojoType="dojox.mobile.RoundRectList"> <li dojoType="dojox.mobile.ListItem">List Item 1</li> <li dojoType="dojox.mobile.ListItem">List Item 2</li> <li dojoType="dojox.mobile.ListItem">List Item 3</li> <li dojoType="dojox.mobile.ListItem">List Item 4</li> <li dojoType="dojox.mobile.ListItem">List Item 5</li> </ul> </div>
保存 index.html 文件 ( File -> Save),确保将 Xcode 左上角的 Overview 工具栏选项设置为 Simulator 目标。现在可以使用 Build and Run ( Build -> Build and Run) 来启动应用程序。Xcode 会花费一些时间来启动 iOS Simulator 应用程序。在此之后,您的原生 Dojo 应用程序应该会启动。您可能会注意到,在屏幕的底部没有 Safari 工具栏,而且应用程序占据了整个设备屏幕,参见图 17。
如果通过在模拟的 iPhone 上选择 Home 退出应用程序,应用程序在设备的主屏幕上显示为默认的 PhoneGap 应用程序图标和名称HelloNative,参见图 18。
如果在模拟器中打开另一个应用程序(比如 Safari 或 Contacts),两次触碰 Home 按钮,会打开 iOS Multi-tasking 菜单。您会再次看到自己的应用程序的图标,可以在其他应用程序和自己的应用程序之间快速轻松地切换。
部署到其他平台的过程通常与这里描述的一样简单,但是将应用程序部署到 Android 可能需要做一些调整。可以在 PhoneGap 网站上找到您需要的所有信息。如果计划分发应用程序,或者您应用程序二进制文件偏大,请记得创建一个自定义 Dojo 构建版本。
结束语
移动 Web 应用程序正在快速发展,它会成为原生移动应用程序开发的合理的、强大的替代方法。在本文中,我们了解了 Dojo Mobile 这样的移动 HTML5 框架如何提高开发过程的价值,简化为移动设备设计 UI 组件和小部件的繁琐工作。Dojo Mobile 甚至为不同类型的设备提供了不同的主题。
构建移动 Web 应用程序之后,可以使用表现出色的 PhoneGap SDK 将应用程序以原生方式部署到多个目标平台上。甚至可以利用相机和麦克风等原生设备特性。移动 Web 的未来不仅非常光明,而且就在眼前。
原文出处:IBM developerWorks