内容


Android 和 iPhone 浏览器之战,第 1 部分

WebKit 成援兵

为浏览器构建一个网络监视应用程序

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: Android 和 iPhone 浏览器之战,第 1 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:Android 和 iPhone 浏览器之战,第 1 部分

敬请期待该系列的后续内容。

简介

iPhone 和 Android 平台加起来已经有 10 万多个应用程序可供从二者各自的应用程序库下载。本机应用程序指的是那些用某个平台的 SDK 构建、然后再编译和安装到某个设备上的应用程序。这些本机应用程序提供了对该设备固有功能的全面访问,包括诸如无线联网、蓝牙、数据存储、加速计、指南针和其他使这些设备变得十分吸引人的出色功能。虽然面向 iPhone 和 Android 平台的本机或定制应用程序极为普及,但移动 Web 应用程序也开始展露了巨大的潜力。移动技术渐趋成熟 — 移动 Web 也随之而来。

本文是由两部分组成的系列文章的第一篇,这个系列主要围绕的是开发面向 iPhone 和 Android 的基于浏览器的应用程序,旨在帮助您开发您自己的移动 Web 应用程序。移动 Web 应用程序的威力不仅仅是在一个移动设备上呈现一个网站。我们还将接触到使移动 Web 开发如此势不可挡的某些核心技术和技巧。

Web 已经成为了平台的不二之选,因为它解决了困扰应用程序开发人员和系统管理员的诸多问题。如下例举了其中的几个解决方案:

  • Web 应用程序容易部署 — 只需将它们安装或复制到服务器,并让您的客户将其浏览器指向正确的 URL。
  • Web 应用程序在高性能的数据中心内可以由服务器群很好地伸缩并能被既有的网站管理工具服务。
  • Web 应用程序集中化数据存储并进而简化了灾难恢复计划。
  • HTML、Cascading Style Sheets (CSS)、JavaScript 以及图像的综合提供了一种优化的用户界面体验,远远超出了本机 SDK(缺少一种全身心投入的浸入式的游戏体验)的能力并且大多数应用程序体验均不保证游戏或 kiosk 体验。
  • 大多数应用程序要求简单易用的 UI 元素来指导用户进行一系列的日常操作。

Web 应用程序发布模型的一个最为吸引人的地方是将软件转变为一种面向订阅的服务,这是一种实实在在的双赢。“为什么?”您不禁要问。让我们一起来看一看。

Web 部署模型允许顾客在购买之前先试用,这样以来,就将顾客的风险和成本减到了最少。如果顾客对试用很满意,那么只需进行一次信用卡(或 PayPal)支付就可以继续使用此服务。软件供应商亦可以从中受益,因为系统升级被大大简化,减少了支持成本并最终减少了转嫁到顾客上的成本。并且,SaaS(software as a service)模型还让顾客在享受了软件的种种好处的同时,无需大量的预先投入 — 投资回报在同一个月就可实现,而不是在不可预知的未来。

听起来不错。适合 Web 的概念同样对移动奏效么?这个问题的答案常常是否,直到 iPhone 的出现。为何如此呢?

实际情况是移动 Web 浏览器体验一直非常缺乏。但这一切有了改观,这要归功于一种新技术的出现,即 WebKit,而 iPhone 则让 WebKit 成为了移动领域标志性的大事件。

在短短几年时间内,iPhone 已经从最初的尝试之举成为了移动 Web 客户机的鳌头。为何如此?因为 WebKit 加上可靠的 Internet 连接使得 Web 同样适于移动 — 并且与到目前为止的任何其他的浏览器相比,这一点尤其突出。移动市场的其他玩家已经注意到了这一动态并正在开始使用 WebKit,或正在重新审视它,当然也有人反对它。

那么,什么是 WebKit?

WebKit 和 HTML5

WebKit 是一种浏览器引擎,支撑着 iPhone 内的 Mobile Safari 浏览器以及 Android 内的浏览器背后的技术。WebKit 也在其他的移动环境内有自己的用武之地,但是我们还是将我们的讨论集中于 iPhone 和 Android 平台。

WebKit 是一个开源项目,其起源可追溯到 K Desktop Environment (KDE)。WebKit 项目催生了面向移动设备的现代 Web 应用程序。虽然设备本身的能力和形态因素都相当重要,但移动用户最热衷的仍然是内容。如果移动用户可用的内容只是 Internet 用户可用内容的一个很小的子集,那么用户体验充其量也只能划分为二等。

我们当中的大多数人都更希望生活是连贯的 — 如果我们在家中的笔记本上访问了一个网站,我们同样希望在火车上旅行时仍然访问到同样的内容。内容是最好的应用程序。不管我们身在何处、在做什么,我们都想要访问到我们的数据。WebKit 让 iPhone 和 Android 平台上可以有丰富的内容。

有一点很值得注意,即 WebKit 还应用在了桌面的 Safari 浏览器内,该浏览器是 Mac OS X 平台默认的浏览器。不管我们讨论的是桌面版本还是 iPhone 或 Android 上的浏览器引擎,WebKit 均优先支持 HTML 和 CSS 特性。实际上,WebKit 还支持尚未被其他浏览器采纳的一些 CSS 样式 — 这些特性正在得到 HTML5 规范的考虑。

HTML5 规范是一个技术草案集,涵盖了各种基于浏览器的技术,包括客户端 SQL 存储、转变、转型、转换等。HTML5 的出现已经有些时间了,虽然尚未完成,但是一旦其特性集因主要浏览器平台支持的加入而逐渐稳定后,Web 应用程序的简陋开端将成为永久的记忆。Web 应用程序开发将成为主导 — 并且不只是在传统的桌面浏览器空间,还将在移动领域。移动将一跃成为首要考虑,而不再是后备之选。

移动 Web 应用程序的考虑

为了访问 Web 开发技术,如今,应用程序开发人员有几个选择。第一,应用程序可严格编写为服务器上的 HTML、CSS 和 JavaScript 文件。当然,HTML 内容可以产生自静态 HTML 文件,也可以从任何的服务器端技术(比如 PHP、 ASP.NET、Java Servlets 等)动态生成。所有这些技术追根到底都可简单地用术语 HTML 指代 — 这不是本文讨论的重点所在 — 并且最为重要的是,受 WebKit-支撑的浏览器能够在移动设备上解析和呈现 HTML。

用户通过在移动设备上(即 iPhone 或 Android)打开浏览器应用程序并输入目标服务器对应的 URL:http://yourcompanyname.com/applicationurl 来访问 Web 应用程序。

特定的某个移动 Web 应用程序总是能找到自己的位置:从一般的 Web 站点到高度特定于平台的移动 Web 应用程序。

一般站点的呈现

WebKit 内的呈现引擎,再配以 iPhone 和 Android 平台上的高度直观的 UI,实际上就使得几乎任何一个基于 HTML 的 Web 站点都能呈现在此设备上。Web 页能被正确呈现,不再像原来的移动浏览器体验:内容被包裹起来或是根本不显示。当页面加载后,内容通常被完全缩放以便整个页面都可见,尽管内容会被缩放得非常小,甚至不可读,如图 1 所示。不过,页面是可滚动、放大、缩小的,这就提供了对全部内容的访问。默认地,浏览器使用 980 像素宽的视见区或逻辑尺寸。

图 1. 加载时 Web 页面被完全缩小
当页面加载后,内容通常被完全缩小以便整个页面都可见,但是会被缩放得非常小
当页面加载后,内容通常被完全缩小以便整个页面都可见,但是会被缩放得非常小

尽管这能提供对整个页面的访问,是原来的移动 Web 体验上的一个巨大进步,但还是需要做很多事情才能进一步改进移动体验。

移动友好性

要想使 Web 页面从一般的页面变成支持移动设备的页面,Web 应用程序可以在几个方面进行修改。

虽然页面可以在 WebKit 中正确呈现,但是,一个以鼠标为中心的设备(比如笔记本或台式机)与一个以触摸为中心的设备(比如一个 iPhone 或 Android 智能手机)还是有区别的。其中主要的一些差异包括 “可单击” 区域的物理大小、“悬浮样式” 的缺少以及完全不同的事件顺序。如下所列的是在设计一个能被移动用户正常查看的 Web 站点时需要注意的一些事情:

  • iPhone/Android 浏览器呈现的屏幕是可读的 — 大大好于传统的移动浏览器 — 所以不要急于草草制作您网站的移动版本。
  • 手指要大过鼠标指针。在设计可单击的导航时要特别注意这一点 — 不要把链接放得相互太靠近,因为用户不太可能单击了一个链接而不触及相邻的链接。
  • 悬浮样式将不再奏效,因为用手指不能进行用鼠标指针进行的 “悬浮”。
  • 诸如 mouse-down、mouse-move 等事件在基于触摸的设备上自然大相径庭。这类事件中有一些将被取消,不要指望移动设备上的事件顺序与桌面浏览器上的一样。

这其中的细节在 iPhone in Action 内有详述(参见 参考资料)。而从我们的目的考虑,我们将更多地着重于 WebKit 所能做的,而不是它不能做的。

让我们来看看要使一个 Web 站点对 iPhone 或 Android 访客具有友好性所面临的最为明显的一个挑战:屏幕大小。我们今天使用的实际移动屏幕尺寸是 320x480。请注意由于用户可能会选择横向查看 Web 内容,所以屏幕大小也可以是 480x320。正如我们在图 1 中看到的,WebKit 将能很好地呈现面向桌面的 Web 页面,但是文本可能会太小以至于若不进行缩放或其他操作就无法有效阅读内容。那么,我们该如何应对这个问题呢?

最为直观也是最不唐突的适合移动用户的方式是通过使用一个特殊的 metatag:viewport

metatag 是一个放入 HTML 文档的 head 元素内的 HTML 标记。如下是一个使用 viewport 标记的简单例子:<meta name="viewport" content="width=device-width" />。当这个 metatag 被添加到一个 HTML 页面后,我们看到此页面被缩放到更为适合这个移动设备的大小,如图 2 所示。如果浏览器不支持此标记,它会简单地忽略此标记。

图 2. 页面被缩放到更为适合这个移动设备的大小
当这个 metatag 被添加到一个 HTML 页面后,我们看到此页面被缩放到更为适合这个移动设备的大小
当这个 metatag 被添加到一个 HTML 页面后,我们看到此页面被缩放到更为适合这个移动设备的大小

在某些情况下,最为理想的方式是提前将窗口缩放到一个合适的值,如图 3 所示。

图 3. 提前缩放窗口
最为理想的方式是提前将窗口缩放到一个合适的值
最为理想的方式是提前将窗口缩放到一个合适的值

为了设置特定的值,将 viewport metatag 的 content 属性设为一个显式的值: <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=yes" />。通过改变初始值,屏幕就可以按要求被放大或缩小。将值分别设置在 1.0 和 1.3 之间对于 iPhone 和 Android 平台是比较合适的。viewport metatag 还支持最小和最大伸缩,可用来限制用户对呈现页面的控制力。

自具有 320x480 布局的 iPhone 面世以来,其形态系数就一直没有改变过,而随着来自不同制造商、针对不同用户群的更多设备的出现,Android 则有望具备更多样的物理特点。在开发应用程序并以诸如 Android 这类移动设备为目标时,一定要考虑屏幕尺寸、形态系数以及分辨率方面的潜在多样性。

除了 Android 设备与其他设备之间的这些物理差异之外,经验还表明 Android 的软件还通过设备内置的(on-device)浏览器设置对页面的呈现实施了更多控制。不仅稳定,Android 平台还很灵活。取决于 SDK 等级和制造商,某个设备上的设置很可能不同于您的开发环境。图 4 显示了取自 Android Emulator V1.6 的浏览器应用程序的设置页面。这个设置屏幕允许用户将一个设备设置为一个预先定义的缩放等级(far、near、medium)或请求此设备自动适应页面。

图 4. Android Emulator 的设置页面
取自                 Android Emulator V1.6 的浏览器应用程序的设置页面
取自 Android Emulator V1.6 的浏览器应用程序的设置页面

在移动世界,变化无时无刻不在发生,我们这里所讨论的也不是一成不变的。比如,针对浏览器 Sprint Hero 的设置就页面呈现而言具有完全不同的一组选项集。Hero 构建于 Android V1.5 之上外加一些 HTC-提供的增强。幸运的是,如果呈现在您的 Web 页面内,这些设置将被 viewport metatag 覆盖。

迄今,我们已经看到了 WebKit 能很好地呈现一个常规的 Web 页面,尽管在不进行缩放的情况下,页面有些小并很难阅读。接下来,我们将实施更多的控制,即通过使用 viewport metatag 控制页面如何在设备上被查看。这就使得页面更易读和易于导航。但是如果我们想要更进一步,让站点看起来和感觉上更像一个移动应用程序,该如何做呢?

为移动量身打造

现在,让我们来看看以移动用户为目标进行设计时所应采用的设计策略。我们举一个简单的例子,让我们来看看 Google 的 GMail 电子邮件服务的登录页面。

先来看看这个桌面浏览器体验,如图 5 所示。

图 5. 桌面浏览器
桌面浏览器体验
桌面浏览器体验

这个桌面主屏幕在左边具有信息性内容,在右边有一个登录区域。将这个桌面视图与图 6 内所示的特定于移动的视图(取自 iPhone)相比较。

图 6. 来自 iPhone 的特定于移动的视图(
来自 iPhone 的特定于移动的视图
来自 iPhone 的特定于移动的视图

图 6 内的屏幕很显然针对的是一个移动用户。此用户被直接提示继续运行这个应用程序所需采用的步骤 — 无需缩放或滚动。

接下来,让我们看看这个移动 GMail 应用程序在阅读消息时的功能。由于可被这个应用程序使用的资产有限,消息阅读窗口很少有机会展示按钮或导航。任何专用于导航的空间都会占用用于阅读内容的空间。而且,如果我们能够避免,我们绝对不想使用多个框架或滚动 div 元素。移动 GMail 通过提供一个简单的、能在页面停止滚动时就立即出现的浮动菜单解决了这个问题。此菜单具有三个按钮: ArchiveDeleteMore。选择 More 按钮,还会显示出额外的菜单项,如图 7 所示。

图 7. 浮动菜单
选择 More 按钮,会显示出额外的菜单项
选择 More 按钮,会显示出额外的菜单项

这个应用程序就是为移动量身定做的。

另一个需要留意的事情是我们不想让运行着功能强大的浏览器(例如运行于 iPhone 或 Android 平台上的浏览器)的那些访客的移动体验大打折扣。最后,请看 GMail 在页面底部所显示的内容,如图 8 所示。

图 8. 让用户决定
让用户决定
让用户决定

如果用户倾向于桌面版本更为强大的功能,那么就让他使用。只要可能,就让用户决定。

现在,我们假设需要构建一个使用 Web 技术的应用程序,但该程序必须实际看上去更像是一个本机应用程序。

特定于平台的内容

下一个步骤是创建特定于平台的内容,通过格式化一个页面以使其看上去更接近目标平台的本机感观,而不是一般的 Web 站点。本机究竟是何意思?

在深入挖掘如何让一个 Web 页面的观感更像是目标平台的一个本机应用程序之前,让我们先花点时间,比较一下 iPhone 和 Android 作为平台在视觉效果方面的差异 — 暂时不考虑二者很强的基于服务器的相同点。

iPhone 的观感很独特。如果把 iPhone 的一个屏幕快照显示给别人看,除非这个人一直居住于荒野,否则他很可能会一眼就识别出该屏幕快照来自一个 iPhone。但是如果把 Android 设备的屏幕快照给人看,那么结果很可能不同。为什么会如此呢?可能的原因有几个。主要的原因在于 iPhone 上市已久并且拥有大量的近乎狂热的拥护者。为了购买价格不菲的限量版特制 V1 iPhone,人们不惜排数小时的队。不管您有没有一台 iPhone,Apple 的这一杰作都已经是当今市场中的偶像产品。那么,Android 境况如何呢?

Android 还相对较新,并且在很多方面都与 iPhone 相悖,比如它接纳开源社区。Android 将被用在多个设备上(电话和其他家用电器类型的设备)。目前,我们的讨论只限于移动手机以便让事情尽量地简化。

随着时间的推移,全球范围内面向 Android 的设备数量将有可能超过 iPhone。这是因为受 Android 支撑的设备由多个厂商制作并将可在多个运营商网络上应用。随着加入到 Android 市场的玩家的增多,在感观方面自然要有分别。从 HTC 提供的 SenseUI 界面不难看出这一点。这种诱人的观感在核心 Android SDK 内并不具备,而且并不是与所有设备兼容。Motorola、Google 和 Verizon 已经结成团队来共同创建一种新的 Android 设备:DROID。它是第一个运行在 2.0 平台上的商业 Android 设备。

对比 Android 的多样性与 iPhone 的统一外观。iPhone 是 Apple 公司一个极具竞争力的专有产品。iPhone 的外观可能会与时俱进,但是几乎不太可能出现较大差别,而 Android 在其早期就经历了分别和差异。

那么,我们如何才能得到一个本机的观感呢?

在 Web 2.0 出现以前,这将是一个很大的挑战。为了支持多个客户浏览器(移动的和非移动的)所进行的早期尝试包括几个不同的技术,比如:

  • 完全并行的站点
  • 基于 userAgent 动态生成的内容
  • Proxy 服务器将内容提取到设备;RIM 已经将这种方式大量应用在了设备内置的电子邮件呈现中并取得了成功。

这些方式对于资金充足的大型团队而言可能是可以接受的,但是其他的情况又当如何呢?我们不具备时间、人力或资金来换取这种功能。并且,我们经过深思已经认识到昨天的移动 Web 的不足,所以我们决不想重蹈覆辙。

幸运的是我们不必如此。在 WebKit 和 CSS 的年代,这些差异已经通过样式表和媒体查询(media query)的使用得到了妥当的解决。正如之前介绍的,一个媒体查询是一种获得客户相关信息的技术。之前的传统做法是,浏览器发送一个 userAgent 字符串,用来标识此浏览器,而服务器则负责确定该向这个设备发送哪些内容(根据上述讨论)。而有了媒体查询,浏览器就可以基于其能力作出决定。下面就是获得针对 smartphone 的样式表的例子: <link rel="stylesheet" type="text/css" href="smartphone.css" media="only screen and (max-device-width: 480px)" />。而这里则是一个针对桌面计算机的媒体查询: <link rel="stylesheet" type="text/css" href="smartphone.css" media="only screen and (min-device-width: 481px)" />

要更多地了解媒体查询,请查阅相关的草案规范(参见 参考资料)。

接下来,我们将着重介绍一个例子,以展示这种方式在用以显示网络状态的示例应用程序的上下文中的应用。

网络监视应用程序

此应用程序的目的是为了监视多个服务器。独立的软件开发人员通常会跨多个服务器支持多个应用程序。如果在这个领域的从业时间很长,那么服务器的类型以及应用程序的类型就更有可能不同。所有这些只是为了说明一个简单的工具无法监视各个应用程序的各个方面。这也是引入 Network Monitor (netmon) 移动应用程序的原因所在。它并未被设计成在移动设备上面面俱到,而是灵活和方便的。

netmon 应用程序包含感兴趣的服务器列表。其中的每一项显示关键性能指示器(KPI)。 KPI 很早就被 MBA 学生用来衡量一个企业运转是否健康。在 Web 应用程序托管领域,一些重要的 KPI 有:

  • 在最近一段时期内事务的数量:
    • 订单
    • 目录请求
    • E-mail 消息
    • 页面浏览量
  • 自上一次事务后的一段时期:
    • 订单
    • EDI 文档
    • 业务伙伴消息
    • 来自供应商的 FTP 文件
  • 数据库是否可用?
  • 最后一次已知备份的日期
  • 每个订单的平均金额
  • 剩余的磁盘空间
  • 过去一个小时、一天、一个月内所传输的带宽

这些数据项和任何其他的操作数据都是为了给出特定系统或应用程序的健康状况。在节日期间,我们会实际察看在我们的一些站点上的订单数。如果订单数没有出现逐小时稳步增长,那么我们就需要进一步探查问题了。

由于每个应用程序的需要以及所需资源不同,因而 netmon 应用程序必须灵活才能适应于每个应用程序的特殊性。为了满足灵活性的要求,我们用一个最为基础的数据结构来代表特定应用程序的健康状况;在本系列的第 2 部分,我们将着重关注于这些数据从何而来以及如何更新。现在,我们只需关心如下所列的信息:

  • 站点的名称
  • 站点 URL(主页)
  • 要更新的 URL
  • 状态:OK 与否?
  • 总结:对条件的大致描述;或者是 OK,或者是一个文本式的字符串来描述最高优先级的问题
  • 条目:这是用来表达站点的当前操作数据或 KPI 的名称/值对的集合。

我们的应用程序将以一种易于导航的方式列出这些条目、利用 CSS、jQuery 和 WebKit 功能来使这些项突出出来。正如之前所提到的,我们的目标是为了让此应用程序能够运行在 iPhone、Android 以及 Safari 的桌面版本之上。

构建一个应用程序

如今,Web 页面应该以一种声明式的方式创建,只提供组织和内容。所有定位和格式化都通过 Cascading Style Sheets 实现,并通常还有 JavaScript 的协助。实际上,JavaScript 库已经如此流行以至于成为了一种规范,而不再是例外。在本文的示例应用程序内,我们使用了流行的 jQuery JavaScript 框架。这个示例应用程序将呈现在 iPhone、Android 以及桌面上。HTML 内容则完全相同。差异存在于选中的样式表。提醒您:我们并未对如何让应用程序的外观光鲜诱人给予过多的关注。实际上,为了突出此应用程序的样式表组织,我们过多地强调了背景颜色。我们将在本系列的第 2 部分中全面讨论应用程序的外观。应用程序相应的 HTML 如清单 1 所示。

清单 1. 此应用程序的 HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="netmon.css" type="text/css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="netmon.js"></script>

<script type="text/javascript">
   if (navigator.userAgent.indexOf('iPhone') != -1) {
      document.write('<link rel="stylesheet" href="iphone.css" 
type="text/css" />');
   } else if (navigator.userAgent.indexOf('Android') != -1) {
      document.write('<link rel="stylesheet" href="android.css" 
type="text/css" />');
   } else {
      document.write('<link rel="stylesheet" href="desktop.css" 
type="text/css" />');
   }

function setupTestData() {
   try {
      netmon.initialize();
      if (netmon.resources.length > 0) {
         jQuery.each(netmon.resources,function (index, value) {
            $("#mainContent").append(netmon.render(index,value));
         });
         $(".serverentry").click (function() {$(this).find(".serveritems").toggle();});
         $(".serveritems").hide();
      }
   } catch (e) {
      alert(e);
   }
}
   
</script>
   
<title>My Network Resources</title>
</head>
<body onload="setupTestData();">
<div id="mainContainer">
   <div id="header">
      <h1>My Servers</h1>
   </div>
   <div id="mainContent">
   </div>
   <a href="q.php">My User Agent</a>
</div> 
</body>
</html>

快速浏览一下上述的 HTML,不难发现有如下几个点需要注意:

  • 其中有两个外部加载的 JavaScript 文件:一个针对的是 jQuery 库,一个针对的是我们应用程序的 helper 函数。
  • 使用 viewport metatag 来调整内容的呈现伸缩。
  • 加载了一个主样式表: netmon.css。
  • 询问 userAgent 来决定要加载哪个额外的样式表:一个面向 iPhone,一个面向 Android,还有一个面向 Desktop。
  • 当页面加载时,数据的显示通过 jQuery 以及 netmon.js 文件的一个 helper 函数实现。
  • 页面内还包含若干 div 标记。
  • 最后,这里还有一个页面链接以显示 userAgent 字符串。它之所以存在是考虑到方便性和展示的目的。它与应用程序本身无关。

在深入研究这些样式表以及 netmon.js 文件之前,让我们先来看看当前的这个应用程序。还记得吧,我们针对三个受支持的平台使用了三个不同的样式表。并且每一个都是用不同的背景颜色设置好的以协助开发过程。 图 9 显示了这个具有蓝色背景的 Desktop Safari 浏览器。

图 9. 显示在桌面 Safari 浏览器内的应用程序
具有蓝色背景的 Desktop Safari                 浏览器
具有蓝色背景的 Desktop Safari 浏览器

图 10 显示了在 Android 浏览器内呈现的这个具有红色背景的应用程序。

图 10. 显示在 Android 浏览器内的应用程序
在 Android 浏览器内呈现的这个具有红色背景的应用程序
在 Android 浏览器内呈现的这个具有红色背景的应用程序

图 11 显示了在 iPhone 浏览器内呈现的这个具有绿色背景的应用程序。

图 11. 显示在 iPhone 浏览器内的应用程序
显示了在 iPhone 浏览器内呈现的这个具有绿色背景的应用程序

在名为 netmon.js 的文件内的主样式表,如清单 2 所示。

清单 2. 主样式表
body {
   color: #888888;
   font-family: Helvetica;
   font-size:14px;
   margin: 0px;
   padding: 0;
}
.details {
   margin: 0px;
   padding: 0px;
   background-color: white;
   border: solid;
   border-width: 1px;

   -webkit-border-top-left-radius: 8px;
   -webkit-border-top-right-radius: 8px;
   -webkit-border-bottom-left-radius: 8px;
   -webkit-border-bottom-right-radius: 8px;
}
.OK {
   color: #000000;
}
.BAD {
   color: #ff0000;
}
.odd {
   background-image: -webkit-gradient(linear, left top, right bottom,from(#ccc) 
,to(#999));
}
.even {
   background-image: -webkit-gradient(linear, left top, right bottom,from(#999) 
,to(#ccc)); 
}
.serverentry a {
   float: right;
   color: #ffffff;
}
.serveritems{
   color: #000;
}

#header h1 {
   margin: 0;
   padding: 0;
   text-align: center;
   color: #000;
}

这些特定于平台的样式表实现了如下三个主要目标:

  1. 更改颜色主题以展示样式表的影响以及基于 userAgent 将某个特定的样式表指向某个特定的平台是多么地简便。
  2. 调整桌面和移动平台之间的字体大小。
  3. 实施特定于 WebKit 的功能。如果我们针对的是桌面上的一个非 WebKit 兼容的浏览器(比如 Firefox)时,这一点将非常重要。

不妨举个例子,iphone.css 文件如清单 3 所示。

清单 3. iphone.css 文件
body {
   background-color: #00ff00;
}
.serverentry {
   -webkit-border-top-left-radius: 8px;
   -webkit-border-top-right-radius: 8px;
   -webkit-border-bottom-left-radius: 8px;
   -webkit-border-bottom-right-radius: 8px;
}
.name {
   font-size: 2em;
}
.summary{
   font-size: 1.5em;
}
.serverentry a {
   font-size: 1.5em;
}

在这个文件内,我们看到主体标记的背景颜色被设为 green (#00ff00),而且还有字体大小上的变化以便使这些条目更适合在移动设备上阅读。

最后,让我们来看看 netmon.js,该文件包含一列条目以及一个被设计用来呈现条目的函数,如清单 4 所示。为了简便起见,有些数据被省略了。完整的副本,请参见 下载

清单 4. netmon.js
var netmon = {
   initialize : function () {
   },
   resources : 
   [
      {
         name : 'msiservices.com',
         homeurl : 'http://msiservices.com',
         pingurl : 'http://msiservices.com/netmon.php',
         status : 'OK',
         summary : 'OK',
         items : 
         [
          {name : 'DiskSpace', value : '22.13 GB'},
          {name : 'Database Up?', value : 'Yes'}
         ]
      },
      {
         name : 'server 2',
         homeurl : 'http://someurl',
         pingurl : 'http://someurl/netmon.jsp',
         status : 'OK',
         summary : 'OK',
         items : 
         [
          {name : 'DiskSpace', value : '100.8 GB'},
          {name : 'Database Up?', value : 'Yes'}
         ]
      },
// additional entries clipped for brevity

   ],
   render : function(index,itm) {
      try {
         var ret = "";
         ret += "<div class='serverentry " + itm.status + " " + (index % 2 == 0 ? 
'even' : 'odd') + "'>";
         ret += "<span class='name'>" + itm.name + 
"</span>&nbsp;&nbsp;<a target='_blank' href='" + itm.homeurl + 
"'>Show</a><br />";
         if (itm.status != "OK") {
            ret += "<span class='summary'>-" + itm.summary + 
"</span><br />";
         }
         
         ret += "<div class='serveritems'>"; 
         jQuery.each(itm.items,function (j,itemdetail) {
            ret += ">>" + itemdetail.name + "=" + itemdetail.value + 
"<br />";
         });
         ret += "</div>";      
         ret += "</div>";
         return ret;
      } catch (e) {
            return "<div class='error'>Error rendering item [" + itm.name + "] 
" + e + "</div>";
      }
   }
};

借助 CSS 文件内的类定义,当服务器条目没有处于 OK 状态时,它就会被显示为红色。此外,当状态不是 OK 时,我们会显示 summary 字段以便给出问题的一个大致概览。在图 9-11 中,服务器 4 的问题是磁盘空间不足。如果我们轻击一个条目,就能看到其细节,如图 12 所示。

图 12. 服务器 4 的细节
当单击一个条目时,显示服务器 4 的细节
当单击一个条目时,显示服务器 4 的细节

通过轻击每个条目右侧的 show 链接,就可以启动每个服务器的主页。这个特性十分得心应手,原因有两个。一是记住所感兴趣的每个服务器的 URL 是件很繁琐 的事情,其二,不管移动设备的键盘有多棒,要求在移动设备上键入这么长的 URL 就更繁琐了。

在我们的移动设备上,netmon 正在快乐地运行着,那么支持我们的服务器应该是更为容易的一项任务。

在第 2 部分,我们将充实这个应用程序以便我们能请求更多实时数据,并会讨论构建一个移动应用程序时有关服务器端的考虑事项。

在结束本文之前,让我们快速浏览一下要让这个应用程序可从应用程序库下载需要做些什么。

将一个 Web 应用程序付诸使用

假设,这个网络应用程序已经就绪。您向一个朋友展示了它,您的朋友鼓励您把这个应用程序销售给他人以便他人也可以用您的应用程序来监视其网络上的资源。那么,您能不能销售一个 Web 应用程序呢?一个 Web 应用程序当然可以通过传统的订阅或 SaaS 模型销售,但如果想要将您的 “Web 应用程序” 打包后再通过一个应用程序市场销售它,比如 iTunes App Store 或 Google Marketplace,又该如何呢?为了这个目的,应用程序必须被编译为一个本机应用程序。所幸的是,针对此已经有一个解决方案。

每个主要的移动平台都有一种将浏览器嵌入到视图或表单、动作的手段。每个平台为这种技术所使用的术语稍有不同,但这些技术工作的方式是相似的:在这个本机应用程序放入一个 browser 控件,而这个本机应用程序可以与之交互。在最简单的模型内,这个 browser 控件可能只是访问 Web 以获得内容。当然,这个本机应用程序也可以截获链接请求并提供其自己的内容,进而只利用浏览器视图来进行呈现。请记住,对于本机小部件,HTML 和 CSS 均是可行的,而不管应用程序内容的来源。并且,有些应用程序将是这两种方式的混合。比如,一个应用程序可以从 Web 上获得大多数内容,而应用程序的 “本机” 的一面则提供了通过蓝牙访问本机资源的能力。

对于这类应用程序架构,市场上已经有几个工具可用。PhoneGap 和 Appcelerator 是这一领域的两个佼佼者(参见 参考资料)。

结束语

本文主要介绍了受 WebKit 支撑的 iPhone 和 Android Web 应用程序。在第 2 部分,将对这个示例应用程序进行扩展,会融入通过 Ajax 的 Web 更改技术进行即时页面更新的功能。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=460195
ArticleTitle=Android 和 iPhone 浏览器之战,第 1 部分: WebKit 成援兵
publish-date=01042010