Android上使用的XML.docx

上传人:b****5 文档编号:11631815 上传时间:2023-03-29 格式:DOCX 页数:20 大小:26.16KB
下载 相关 举报
Android上使用的XML.docx_第1页
第1页 / 共20页
Android上使用的XML.docx_第2页
第2页 / 共20页
Android上使用的XML.docx_第3页
第3页 / 共20页
Android上使用的XML.docx_第4页
第4页 / 共20页
Android上使用的XML.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Android上使用的XML.docx

《Android上使用的XML.docx》由会员分享,可在线阅读,更多相关《Android上使用的XML.docx(20页珍藏版)》请在冰豆网上搜索。

Android上使用的XML.docx

Android上使用的XML

Android是针对移动设备的一种新兴的开源操作系统和SDK。

借助它,您可以创建功能强大的移动应用程序。

当您的应用程序可以访问Web服务时,其吸引力会大大增加,这意味着您需要使用Web语言:

XML。

在本文中,您将了解在Android上使用XML的不同方法,以及如何使用它们构建自己的Android应用程序。

入门

在本文中,您将学习如何构建通过Internet使用XML的Android应用程序。

Android应用程序是使用Java™编程语言编写的,因此具备Java技术方面的经验是必需的。

要进行Android开发,您需要使用AndroidSDK。

本文中的所有代码适用于任何版本的AndroidSDK,但SDK1.5_pre是用于开发代码的。

您可以使用SDK和一个文本编辑器来开发Android应用程序,但使用AndroidDeveloperTools(ADT)(一款Eclipse插件)会更加简单。

在本文中,我们使用0.9版本的ADT和Eclipse3.4.2,Java版本。

有关所有这些工具的链接,请参见 参考资料。

Android上的XML

Android平台是一个开源移动开发平台。

它允许您访问各种移动设备的所有方面,这些移动设备从低级图形设备到手机摄像头上的硬件不一而足。

由于Android可以实现这么丰富的功能,因此您可能想知道为何还要为XML伤脑筋呢。

并不是因为使用XML是多么地有趣;而是因为它能提供一些特殊的支持。

XML经常用作Internet上的一种数据格式。

如果您希望通过Internet访问数据,则数据很有可能是XML格式。

如果您希望发送数据给Web服务,那么您可能也需要发送XML。

简而言之,如果您的Android应用程序将利用Internet,那么您可能需要使用XML。

幸运的是,您可以采用多种方法在Android上使用XML。

XML解析器

Android平台最大的一个优势在于它利用了Java编程语言。

AndroidSDK并未向您的标准JavaRuntimeEnvironment(JRE)提供一切可用功能,但它支持其中很大一部分功能。

Java平台支持通过许多不同的方式来使用XML,并且大多数与XML相关的JavaAPI在Android上得到了完全支持。

举例来说,Java的SimpleAPIforXML(SAX)和DocumentObjectModel(DOM)在Android上都是可用的。

这些API多年以来一直都是Java技术的一部分。

较新的StreamingAPIforXML(StAX)在Android中并不可用。

但是,Android提供了一个功能相当的库。

最后,JavaXMLBindingAPI在Android中也不可用。

这个API已确定可以在Android中实现。

但是,它更倾向于是一个重量级的API,需要使用许多不同类的实例来表示XML文档。

因此,这对于受限的环境,比如说Android针对的手持设备,不太理想。

在后续小节中,我们将以Internet上的一个简单的XML源为例,来看看如何在Android应用程序中使用上述各种API来解析它。

首先,我们来看看这个简单应用程序的主要部分,它将通过Internet来使用XML。

Android新闻阅读器

应用程序将从热门Android开发人员站点Androidster获取一个RSS提要,并将它解析为一组简单的Java对象,您可以使用这些对象构建一个AndroidListView(参见 下载 部分获取源代码)。

这是一种典型的多态行为—提供相同行为的不同实现(不同的XML解析算法)。

清单1 展示了如何在Java代码中使用一个接口建立这一模型。

清单1.XML提要解析器接口 

packageorg.developerworks.android;

importjava.util.List;

publicinterfaceFeedParser{

Listparse();

}

在 清单2 中,Message 类是一个典型的PlainOldJavaObject(POJO),它表示一种数据结构。

清单2. Message POJO

publicclassMessageimplementsComparable{

staticSimpleDateFormatFORMATTER=

newSimpleDateFormat("EEE,ddMMMyyyyHH:

mm:

ssZ");

privateStringtitle;

privateURLlink;

privateStringdescription;

privateDatedate;

//gettersandsettersomittedforbrevity

publicvoidsetLink(Stringlink){

try{

this.link=newURL(link);

}catch(MalformedURLExceptione){

thrownewRuntimeException(e);

}

}

publicStringgetDate(){

returnFORMATTER.format(this.date);

}

publicvoidsetDate(Stringdate){

//padthedateifnecessary

while(!

date.endsWith("00")){

date+="0";

}

try{

this.date=FORMATTER.parse(date.trim());

}catch(ParseExceptione){

thrownewRuntimeException(e);

}

}

@Override

publicStringtoString(){

//omittedforbrevity

}

@Override

publicinthashCode(){

//omittedforbrevity

}

@Override

publicbooleanequals(Objectobj){

//omittedforbrevity

}

//sortbydate

publicintcompareTo(Messageanother){

if(another==null)return1;

//sortdescending,mostrecentfirst

returnpareTo(date);

}

}

清单2 中的消息基本上是相当直观的。

通过允许日期和链接作为简单的对象被访问,同时将它们表示为较强类型的对象(java.util.Date 和.URL),它隐藏了一些内部状态。

它是一个典型的ValueObject,因此它基于其内部状态实现了 equals() 和 hashCode()。

它还实现了 Comparable接口,因此您可以使用它进行排序(按日期)。

在实践中,提要中的数据始终是有序的,因为没有必要再进行排序。

每个解析器实现都需要提供一个URL给Androidster提要,并使用它打开一个到Androidster站点的HTTP连接。

这一常见行为自然是在Java代码中建模,我们使用了一个抽象基类,如 清单3 所示。

清单3.基本提要解析器类

publicabstractclassBaseFeedParserimplementsFeedParser{

//namesoftheXMLtags

staticfinalStringPUB_DATE="pubDate";

staticfinalStringDESCRIPTION="description";

staticfinalStringLINK="link";

staticfinalStringTITLE="title";

staticfinalStringITEM="item";

finalURLfeedUrl;

protectedBaseFeedParser(StringfeedUrl){

try{

this.feedUrl=newURL(feedUrl);

}catch(MalformedURLExceptione){

thrownewRuntimeException(e);

}

}

protectedInputStreamgetInputStream(){

try{

returnfeedUrl.openConnection().getInputStream();

}catch(IOExceptione){

thrownewRuntimeException(e);

}

}

}

基类存储 feedUrl 并使用它打开了一个 java.io.InputStream。

如果出现任何差错,它会抛出一个 RuntimeException,造成应用程序出现故障。

基类还为标记的名称定义了一些简单的常量。

清单4 显示了提要中的一些示例内容,以便于您理解这些标记的重要性。

清单4.示例XML提要

xmlversion="1.0"encoding="UTF-8"?

>

--generator="FeedCreator1.7.2"-->

android_news

android_news

Sun,19Apr200919:

43:

45+0100

FeedCreator1.7.2

SamsungS8000toRunAndroid,PlayDivX,TakeOverthe</p><p>World

play-divx-take-over-the-world

MoredetailshaveemergedonthefirstSamsunghandset

torunAndroid.Ayet-to-beannouncedphonecalledtheS8000isbeing

reported...

Thu,16Apr200907:

18:

51+0100

AndroidCupcakeUpdateontheHorizon

on-the-horizon

Aftermonthsofdiscoveryandhearsay,theAndroid

buildthatwehaveallbeenwaitingforisabouttofinallymakeit

out...

Tue,14Apr200904:

13:

21+0100

如 清单4 中的示例所示,一个 ITEM 对应于一个 Message 实例。

项目的子节点(TITLE、LINK 等)对应于 Message 实例的属性。

现在,您已经对提要有了一定的认识,并且已经创建了所有常用部分,接下来看看如何使用Android上可用的各种技术来解析这个提要。

您将从SAX开始。

使用SAX

在Java环境中,当您需要一个速度快的解析器并且希望最大限度减少应用程序的内存占用时,通常可以使用SAXAPI。

这非常适用于运行Android的移动设备。

您可以在Java环境中照原样使用SAXAPI,在Android上运行它不需要做任何修改。

清单5 显示了 FeedParser 接口的一个SAX实现。

清单5.SAX实现

publicclassSaxFeedParserextendsBaseFeedParser{

protectedSaxFeedParser(StringfeedUrl){

super(feedUrl);

}

publicListparse(){

SAXParserFactoryfactory=SAXParserFactory.newInstance();

try{

SAXParserparser=factory.newSAXParser();

RssHandlerhandler=newRssHandler();

parser.parse(this.getInputStream(),handler);

returnhandler.getMessages();

}catch(Exceptione){

thrownewRuntimeException(e);

}

}

}

如果您以前使用过SAX,那么这对您肯定非常熟悉。

与任何SAX实现相同,大多数细节都在SAX处理程序中。

在分解XML文档时,处理程序从SAX解析器接收事件。

在本例中,您创建了一个新的名称为 RssHandler 的类,并将它注册为解析器的处理程序,如 清单6 所示。

清单6.SAX处理程序

importstaticorg.developerworks.android.BaseFeedParser.*;

publicclassRssHandlerextendsDefaultHandler{

privateListmessages;

privateMessagecurrentMessage;

privateStringBuilderbuilder;

publicListgetMessages(){

returnthis.messages;

}

@Override

publicvoidcharacters(char[]ch,intstart,intlength)

throwsSAXException{

super.characters(ch,start,length);

builder.append(ch,start,length);

}

@Override

publicvoidendElement(Stringuri,StringlocalName,Stringname)

throwsSAXException{

super.endElement(uri,localName,name);

if(this.currentMessage!

=null){

if(localName.equalsIgnoreCase(TITLE)){

currentMessage.setTitle(builder.toString());

}elseif(localName.equalsIgnoreCase(LINK)){

currentMessage.setLink(builder.toString());

}elseif(localName.equalsIgnoreCase(DESCRIPTION)){

currentMessage.setDescription(builder.toString());

}elseif(localName.equalsIgnoreCase(PUB_DATE)){

currentMessage.setDate(builder.toString());

}elseif(localName.equalsIgnoreCase(ITEM)){

messages.add(currentMessage);

}

builder.setLength(0);

}

}

@Override

publicvoidstartDocument()throwsSAXException{

super.startDocument();

messages=newArrayList();

builder=newStringBuilder();

}

@Override

publicvoidstartElement(Stringuri,StringlocalName,Stringname,

Attributesattributes)throwsSAXException{

super.startElement(uri,localName,name,attributes);

if(localName.equalsIgnoreCase(ITEM)){

this.currentMessage=newMessage();

}

}

}

RssHandler 类扩展了 org.xml.sax.helpers.DefaultHandler 类。

该类为SAX解析器生成的事件所对应的所有方法都提供了一个默认的非操作实现。

这允许子类根据需要仅覆盖一些方法。

RssHandler 提供了一个额外的API,即 getMessages。

它返回处理程序在从SAX解析器接收事件时所收集的 Message 对象列表。

它有另外两个内部变量,currentMessage 针对被解析的 Message 实例,以及名称为 builder 的 StringBuilder 变量,用于存储文本节点中的字符数据。

解析器将相应事件发送给处理程序时会调用 startDocument 方法,这两个变量的初始化操作就是在此时完成。

查看 清单6 中的 startElement 方法。

在XML文档中每次遇到开始标记时都会调用它。

您只关心该标记何时为 ITEM 标记。

对于这种情况,您将创建一个新的Message。

现在来看 characters 方法。

遇到文本节点中的字符数据时便会调用此方法。

数据只是被添加到 builder 变量中。

最后,我们来看 endElement 方法。

遇到结束标记时会调用此方法。

对于与某 Message 属性相对应的标记,如 TITLE 和 LINK,则使用 builder 变量中的数据在 currentMessage 上设置适当的属性。

如果结束标记是一个 ITEM,则 currentMessage 将被添加到Messages列表中。

所有这些都是非常典型的SAX解析;此处的一切都不是Android所特有的。

因此,如果您知道如何编写JavaSAX解析器,则应该知道如何编写AndroidSAX解析器。

但是,AndroidSDK确实在SAX上添加了一些便捷的特性。

更加简单的SAX解析

AndroidSDK提供了一个名称为 android.util.Xml 的实用类。

清单7 展示了如何使用这个相同的实用类来设置一个SAX解析器。

清单7.AndroidSAX解析器

publicclassAndroidSaxFeedParserextendsBaseFeedParser{

publicAndroidSaxFeedParser(StringfeedUrl){

super(feedUrl);

}

publicListparse(){

RssHandlerhandler=newRssHandler();

try{

Xml.parse(this.getInputStream(),Xml.Encoding.UTF_8,handler);

}catch(Exceptione){

thrownewRuntimeException(e);

}

returnhandler.getMessages();

}

}

注意,这个类仍然使用了一个标准的SAX处理程序,因此您仅仅重用了 清单7 中所示的 RssHandler。

能够重用SAX处理程序是非常不错的,但其代码稍微有些复杂。

您可以想像,如果需要解析一个更加复杂的XML文档,则处理程序可能会带来各种各样的bug。

举例来说,回头看看 清单6 中的 endElement 方法。

注意,在尝试设置属性之前,它检查了 currentMessage 是否为null。

现在,再回头看看 清单4 中的示例XML。

注意,ITEM 标记外部有一些 TITLE 和LINK 标记。

这就是使用null检查的原因。

否则,每一个 TITLE 标记会导致一个 NullPointerException。

Android提供了自己独有的SAXAPI(参见 清单8),它排除了您编写自己的SAX处理程序的需要。

清单8.经过简化的AndroidSAX解析器

publicclassAndroidSaxFeedParserextendsBaseFeedParser{

publicAndroidSaxFeedParser(StringfeedUrl){

super(feedUrl);

}

publicListpar

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1