千锋3G嵌入式移动互联网技术研发中心简介尽管受到媒体追捧,但是开发移动设备应用很多年来一直都是高投入、低回报的工作。基于iPhoneOS和GoogleAndroid的最新一代智能手机提供了一个更简单的应用开发方法:Web应用。这种一次编译就可以支持所有设备的方法可以降低开发成本。更重要的是,所有这些高端设备都具备支持高级HTML、JavaScript和CSS的超现代的浏览器。在本文中,我们将学习如何开发充分利用现代智能手机功能的广泛使用AsynchronousJavaScriptandXML(Ajax)技术的应用。我们将不仅能了解到如何发挥这些设备的最大功效,同时还能学习到如何处理它们之间的细微差别。千锋3G嵌入式移动互联网技术研发中心本文阐述如何开发一个运行在AppleiPhone以及基于Android的智能手机上的移动Web应用。开发这些设备上的移动Web应用,我们不能使用平常的桌面浏览器,至少不能完全只使用桌面浏览器。我们还需要模拟器或实际的设备。对于iPhone来说,我们需要使用iPhone模拟器。它是iPhoneSDK的一部分。本文所使用的是iPhoneSDK3.1。类似地,我们也需要使用AndroidSDK。它包含了一个AndroidVirtualDevice管理器,这个管理器可以用来创建运行各个Android版本的Android模拟器。其中本文使用的是AndroidSDK2.1。本文所用到的大部分代码是JavaScript代码,以及一些HTML和CSS。此外,应用还有一个使用Java™实现的服务器端。这并不是强制性要求的,和其它的Web应用一样,我们可以自己选择使用任意的服务器端技术。我们需要使用Java1.6来运行本文所开发的应用。另外我们还需要使用Jersey,它是JAX-RS的参考实现,以及所有相关的JavaArchive(JAR)文件。千锋3G嵌入式移动互联网技术研发中心移动设备很多年就有Web浏览器了。然而,由于Web开发人员必须处理跨浏览器支持问题,因此开发浏览器应用一直是很困难的。开发人员需要花费很多的时间来实现HTML、JavaScript和CSS在不同版本的浏览器上运行完全一致,如InternetExplorer、MozillaFirefox、Safari等。而桌面浏览器的问题几乎与手机浏览器中的问题如出一辙。不同版本的手机浏览器也是多得惊人。每个设备制造商都拥有各自的浏览器,甚至来自相同厂商的设备在操作系统、屏幕大小等方面都有很大的差别。有些浏览器只支持WAP,而有一些则支持部分的HTML,还有一些完全支持HTML,但不支持JavaScript。幸好,现在情况已经大不相同了。到2010年1月,美国有超过80%的移动互联网流量都是通过iPhone或Android手机产生的。这两种操作系统不仅都是使用WebKit进行HTML/CSS渲染,而且它们都是一样积极地使用HTML5标准所采用的JavaScript引擎。没错。移动领域的主流浏览器现在都使用了开放标准。这是Web开发人员所遇到的最好时机。千锋3G嵌入式移动互联网技术研发中心浏览器之间还是存在差别的,即使是不同版本的iPhone和Android也不例外。其中Android浏览器差别最大。在2.0之前版本的Android上,Android浏览器使用的是私有的GoogleGears技术。虽然Gears有很多优秀的创新技术,现在已经包含在HTML5标准中了。然而,这意味着在很长的一段时间里,Android浏览器是不支持其中一些HTML5标准的,但是我们还是能够使用Gears来实现一部分功能。本文的所有代码都是基于HTML5标准并且是可以正常运行在Android2.0+或iPhone3.0+上的。既然我们已经拥有了这些现代的基于WebKit的浏览器,接下来让我们来看看一些这些设备上的Ajax。千锋3G嵌入式移动互联网技术研发中心像桌面Web应用一样,在移动Web应用上创建引人注目的用户体验的关键通常就是使用Ajax。当然,用户体验并不是使用Ajax的唯一原因;其中还可能涉及到速度和效率的原因。而后者恰恰是在移动Web应用上使用Ajax的更重要的原因所在,因为移动网络的延迟更大,而浏览器本身也受到处理器速度、内存和缓存大小的限制。幸好,由于只需要关注于基于标准的浏览器,因此Ajax则恰好是许多因此变得更简单的技术之一。在详细讨论这个问题之前,让我们先快速地了解一下本文所开发的应用所使用的后台服务器。在开始之前,我们需要下载必要的JAR文件,其中包括Jersey、Xerces、Rome和GoogleAppEngineSDK。然后将它们安装到下面的文件夹中:WebKitBlogwarWEB-INFlib。千锋3G嵌入式移动互联网技术研发中心博客本文的移动Web应用是一个简单的阅读移动Web开发新闻的应用。虽然目前它只是简单地从官方WebKit博客抓取RSS源,但是它可以经过简单地修改来收集多个RSS源。这个应用是一个普通的JavaWeb应用,它可以部署到任何一个Java应用服务器上。所有代码见清单1。千锋3G嵌入式移动互联网技术研发中心类@Path(/feed)publicclassFeed{StringsurfinSafari=@GET@Produces(application/json)publicNewsgetNews(@DefaultValue(0)@QueryParam(after)longafter)throwsException{URLfeedUrl=newURL(surfinSafari);SyndFeedInputinput=newSyndFeedInput();SyndFeedfeed=input.build(newXmlReader(feedUrl));ListItementries=newArrayListItem(feed.getEntries().size());for(Objectobj:feed.getEntries()){SyndEntryentry=(SyndEntry)obj;if(entry.getPublishedDate().getTime()after){Itemitem=newItem(entry.getTitle(),entry.getLink(),entry.getDescription().getValue(),entry.getPublishedDate().getTime());entries.add(item);}}returnnewNews(feed.getTitle(),entries);}}千锋3G嵌入式移动互联网技术研发中心这个类使用Java的JAX-RS创建一个RESTful服务。@Path注释表示了服务的终端,即服务的相对URL是/feed。@GET表示这个服务支持HTTPGET。@Produces声明这个服务将生成JSON格式的数据。这是一个简单的以JSON格式序列化数据的方法。方法getNews接收一个名为after的参数,即获取一个特定日期之后的实体。这里也使用JAX-RS注释来将参数after绑定到查询字符参数after上。如果没有赋值,它会使用默认值0。到这里,我只阐述了清单1中创建服务寻址和数据序列化的代码所用到的JAX-RS注释。该方法的主体实际上大部分依赖于处理RSS的Rome包。它只是下载最新的RSS源,然后将它转换成我们应用所需要的数据,这里的数据就是Item和News这两类。其中唯一复杂的部分是文章的发表日期被转化为一个long值,并用作一个ID。这是一个非常有用的ID,因为我们可以用它来进行排序,我们将在后面使用到。News类如清单2所示。千锋3G嵌入式移动互联网技术研发中心类@XmlRootElementpublicclassNews{privateStringtitle;privateListItementries;//constructors,getters/settersomittedforbrevity}注意News类使用了JAXB注释@XmlRootElement。这个应用中不使用XML,但是JAX-RS使用JAXB完成自动的序列化/反序列化。这个类只有一个标题属性和一组Item。Item类如清单3所示。千锋3G嵌入式移动互联网技术研发中心类@XmlTypepublicclassItem{privateStringtitle;privateStringlink;privateStringdescription;privateLongid;//constructors,getters/settersomittedforbrevity}这个类包含的就是我们在Web应用中显示的内容。类似于News类,它也使用JAXB注释,这样JAX-RS可以将它序列化成JSON。这部分代码的最后一部分是配置Web应用的,以使请求能指向JAX-RS。为了达到这个目的,我们需要编辑应用的web.xml文件,如清单4所示。千锋3G嵌入式移动互联网技术研发中心配置文件?xmlversion=1.0encoding=utf-8?web-appxmlns:xsi=xmlns=xmlns:web=xsi:schemaLocation=version=2.5servletservlet-nameWebKitBlogServlet/servlet-nameservlet-classcom.sun.j