[转帖]构建 Android 手机 RSS 阅读器(一)_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2847 | 回复: 0   主题: [转帖]构建 Android 手机 RSS 阅读器(一)        下一篇 
wei.wang
注册用户
等级:少校
经验:1001
发帖:87
精华:0
注册:2013-8-29
状态:离线
发送短消息息给wei.wang 加好友    发送短消息息给wei.wang 发消息
发表于: IP:您无权察看 2013-9-6 10:34:35 | [全部帖] [楼主帖] 楼主

  如果不能随时了解最喜欢的新闻提要,那么移动计算环境又有什么用呢?当然,可以使用 Android 的浏览器浏览最喜爱的 Web 站点,但遗憾的是,这些站点很可能没有针对两英寸高的屏幕进行优化。此外,您也无法使用其他移动应用程序集成 RSS 或其他 XML 数据以构建自己的 mash-up。本教程将展示如何使用 Android Developer Tools 读取、解析和显示 XML 数据。如果您想在 Eclipse 环境中开始开发 Android 应用程序,请同时学习教程:“用 Eclipse 开发 Android 应用程序”。该教程介绍了如何在 Eclipse 环境中开发 Android 应用程序。



     开始之前本教程介绍了如何在 Android 平台之上处理 XML。要按照本教程构建样例应用程序,必须在开发计算机中安装和运行 Android SDK。推荐使用 Eclipse 构建 Android 应用程序,���不作硬性要求。具备移动开发经验固然有帮助,但是 Android 应用程序开发要求具有 Java™ 编程技能,这将有助于本教程的学习。关于本教程常用缩写词
  • DOM:文档对象模型(Document Object Model)
  • GUI:图形用户界面(Graphical user interface)
  • HTTP:超文本传输协议(Hyper Text Transport Protocol)
  • RSS:真正简单的连锁(Really Simple Syndication)
  • SAX:XML 简单API(Simple API for XML)
  • SDK:软件开发套件(Software Development Kit)
  • XML:可扩展标记语言(Extensible Markup Language)


Android 的 RSS 阅读器为什么值得我们关注?XML 又是如何融入其中的呢?首先,Android 是一种在移动市场中迅速获得广泛关注的平台。甚至在配备了 Android 的消费型设备出现之前,许多开发人员就已纷纷投入到这一移动市场,希望为即将出现的、备受期待的 Android 式设备做好准备。诸如 Android 这样的富设备(Rich device)要求提供内容。某些情况下,内容的表现形式为游戏或一个生产力应用程序。然而,除了移动电子邮件外,最能够驱动数据使用的内容是新闻和信息。这种内容可能看上去类似于与特定金融市场有关的新闻,或者是天气预报这种比较普遍的信息。对于周末想到海边度假的人,自然十分关心天气预报。于是,以一种简单、实用的方式从移动设备获取数据成为了摆在人们面前的一道难题。Android 包含了 WebKit.org 浏览器引擎,这意味着它可以向移动用户交付高质量的浏览器体验。然而,对于一个小型屏幕和有限的输入设备,在多个 Web 站点中查找新闻和消息是非常乏味的事情。不要误会,自从出现 WAP 浏览器和有限的基于文本的信息以来,这一市场已经得到了长足的发展,然而,移动信息的价值在于:输入 RSS 提要时一眼就可以判断出它是否可用。RSS 是 “Really Simple Syndication” 的缩写。实际上,RSS 是一种分布感兴趣的信息的方便方法。RSS 支持 XML 数据;数据包含完整信息源的简单摘要。如果对这些摘要该兴趣,用户可以进一步获取信息并获得全部内容。本教程将演示在构建 Android RSS 阅读器过程中涉及到的几个主要的 XML 处理步骤。本教程分为以下小节:
  • RSS 基础
  • Android RSS 阅读器应用程序架构
  • 使用 SAX 获取并解析 XML 数据
  • 使用 Android 呈现 RSS 数据




先决条件本教程需要结合使用几种技术。需要通过以下步骤获得所有这些工具。
  • 从 http://www.eclipse.org/downloads 下载 Eclipse。
  • 要安装 Android Developer Tools(Eclipse 插件),请按照 Android 文档 “安装 Android SDK” 中的说明操作。
  • 在 http://code.google.com/android 中下载 Android SDK。Android SDK 是一个不断发展的项目。撰写本教程时 SDK 的最新版本为 m5-rc14。
  • 选择一个 RSS 提要。本教程使用 developerWorks Web 站点中最受欢迎教程的提要。
  • 建立一个活动的 Internet Connection 来运行示例应用程序。
完整的源代码可以从 下载 小节获得。本教程包含的源代码片段包括:
  • AndroidManifest.xml 片段:该文件是 Android 应用程序的应用程序部署描述符。
  • RSSReader:该类实现主 GUI 并包含菜单处理代码。
  • RSSFeed:该类含有一个经过解析的 RSS 提要,包含 RSS 通道信息和一组 RSSItems。
  • RSSHandler:该类实现 SAX 解析器处理程序,从而实现对 XML 流(Internet 中的 RSS 提要)的解析并填充一个 RSSFeed 实例。
  • RSSItem:该类表示解析 XML 流得到的一个 RSS 项。
  • ShowDescription:这是一种行为(Activity),显示所选的 RSSItem 的摘要并包含可链接的文本,可以无缝启动 Android 浏览器来访问 RSSItem 中的可用链接。启用这一 Activity 将在伪同步调用中结合使用一个 Intent 和额外的 Bundle。
  • R.java:该文件表示应用程序使用的 GUI 标识符。
术语构建一个 Android RSS/XML 应用程序需要 XML、RSS 和 HTTP 方面的知识,还需要了解 Android 平台的各个方面。了解下面的术语对于学习本教程大有裨益。要想了解关于这些主题的更多信息,请参见 参考资料 中的链接。
  • Android:Open Handset Alliance 的旗舰产品。这是一个针对手机等移动设备的开源操作环境。
  • RSS:Really Simple Syndication 是一种可以通过高效的方式发布信息的数据格式。
  • XML:eXtensible Mark-up Language 是一种自描述性的数据格式。
  • HTTP:Hyper Text Transport Protocol 几乎专门用来传输所有的 RSS 提要。
  • 解析器(Parser):这个工具的作用是从一种格式中提取信息并使信息可用于其他结构。例如,XML 解析器可以从一个 XML 数据源提取数据。
  • 模拟器(Emulator):这种软件工具代表另一种系统。Android 目前���不能用于真实的用户硬件平台;本文在 Android Emulator 上运行示例应用程序。




    RSS 基础介绍在详细介绍下载 RSS 提要并使用基于 Android 的 RSS 阅读器进行处理之前,让我们首先简要回顾一下使用 RSS 的需求、位置以及它的结构。为什么使用 RSS?信息传播工具多种多样,包括可以免费收听的无线电广播、公共和有线电视、印刷媒体,甚至包括 Internet 这样颠覆性的技术,以及其庞大的 Web 站点和电子邮件订阅。虽然选择很多,但是这些工具都存在一个问题:很难在庞杂的海量数据中精确查找到真正感兴趣的信息和价值。幸运的是,RSS 可以帮助我们解决这个问题。RSS 是 “Really Simple Syndication” 的缩写。RSS 是一种内容发布者用来发布信息的 XML 数据格式,这些信息经过了分类并适合人机阅读。RSS 提要通常使用诸如新闻阅读器这种人类可读的友好格式进行处理并显示给用户,本教程中构建的应用程序就是这样一种新闻阅读器。RSS 提要同样可以供计算机使用,从而生成后续的、聚合的信息源。举例来说,定期检索并提供给旅行社本地预订系统的租赁列表就是一个机器使用 RSS 提要的例子。在讨论新闻内容时经常会提到 RSS,然而,除新闻以外,这种格式可用于组织和发布其他很多类型的信息。例如,很多 Web 站点都发布可用的 pod-cast 的 RSS 提要,从而发布音频和视频内容。Handango.com 是一个流行的移动软件和内容的在线商店,它根据移动平台分类,提供新的流行软件标题的提要。例如,提供针对 Windows® Mobile、Blackberry、Palm 和其他平台的提要。用不了多久,很可能就会提供针对 Android 应用程序的提要了!RSS 的格式是 XML 数据,这表示数据本身就包含描述性元素,也就是说它是自包含的。随着行业的逐步规范化,XML 结构在过去几年也经历了一些变化。最新的版本也是应用最广的版本是 2.0。RSS 2.0 是一种相对简单的 XML 结构,很容易由计算机程序解析。在本教程中,我们将解析从 IBM developerWorks Web 站点获得的一条 RSS 提要。


    RSS version 2.0关于哪一个版本最流行已经进行了太多的讨论,现在让我们了解一下 RSS 2.0 规范。RSS 2.0 格式只包含有限的标记。<?xml> 是一个强制使用的标记,所有 XML 文档都需要使用到。第一个标记实际是 <rss> 标记,它以属性的形式包含版本。<rss> 标记是一个或多个通道,每个通道都包含如清单 1 所示的元素。
清单 1. RSS 2.0 中的通道和元素

  1. <channel>
  2. <title/>
  3. <link/>
  4. <description/>
  5. <pubDate />
  6. <language/>
  7. <copyright/>
  8. <image>
  9. <title />
  10. <url />
  11. <link />
  12. </image>
  13. + <item />
  14. </channel>
  15. </rss>

复制代码


每个通道可能含有一个或多个项。每个项具有如清单 2 所示的结构。
清单 2. 项结构

  1. <item>
  2. <title />
  3. <description />
  4. <link />
  5. <category />
  6. <pubDate />
  7. </item>

复制代码





数据使用RSS 提要的使用者可以决定如何显示数据。通常,RSS 阅读器将显示一些有关可用通道的标题信息,包括发布日期(包含在 pubDate 元素中)。注意,RSS 是用于发布相关的即时数据,因此不应该忽视发布日期。图 1 演示了本教程中运行的示例应用程序,它显示了一条 RSS 提要。图 1 显示了 RSS 提要的标题、发布日期,并使用列表(List)格式显示提要项。本教程后面的内容讨论将解析得到的 RSS 提要提供给 Android 用户界面的机制。
图 1. 运行中的 Android RSS 阅读器

北京联动北方科技有限公司

RSS 提要的 item 标记中的元素描述提要中包含的所有项。例如,在本教程中,您要处理的 RSS 提要中包含来自 IBM developerWorks 站点中的一组受欢迎的教程。提要中的每个条目都提供了足够的信息,使用户充分了解提要的主题以及如何获取更多信息。这些信息共分三个级别,每个级别的信息都非常详细。此外,每个条目都包含一个发布日期和类别信息。条目标题简要介绍了提要的主题,例如:<title><![CDATA[Develop Android applications with Eclipse]]></title>。如果您对使用 Eclipse 进行 Android 开发感兴趣的话,那么这个条目标题足够��起您的兴趣。如果用户(即使有应用程序的人员)希望了解更多,则可以获取更多信息,即清单 3 中的描述。
清单 3. 描述

  1. <description><![CDATA[Android is Google's oft-discussed mobile, 
  2. wireless, computer, and communications platform. You can take advantage of 
  3. the powerful Eclipse environment to build Android applications using the Android 
  4. Eclipse plug-in. This tutorial introduces Android application development with the 
  5. Eclipse plug-in, otherwise known as Android Development Tools. The tutorial provides 
  6. an introduction to Android development with a quick introduction to the platform, a 
  7. tour of Android Development Tools, and includes the construction of two example 
  8. applications. ]]></description>

复制代码


注意这里使用了 CDATA XML 技术。如果 XML 提要中包含了可以与所含的 XML 标记进行交互的 mark-up 元素,那么则需要使用 CDATA。CDATA 的一个副作用是数据是按原样获取的,因此您需要对文本进行额外的格式化,以便正确显示到目标用户界面中。本教程后面演示的示例应用程序中将看到这样一个例子。最后,如果用户对这一主题非常感兴趣的话,可以通过提供的链接找到关于这一特定主题的更多信息:

  1. <link>
  2. <![CDATA[http://www.ibm.com/developerworks/edu/os-dw-os-eclipse-android.html?ca=drs-]]>
  3. </link>

复制代码


本教程没有细究对类别的任何特殊处理,这是因为 RSS 提要中的所有类别都是相同的。显示发布日期是一项最佳实践技术。简要介绍了 RSS 及其用途之后,我们来从较高的层次了解一下 RSS 阅读器应用程序的架构。



Android RSS 阅读器应用程序架构一份简短扼要的教程很难详尽地描述如何构建一个功能丰富的 RSS 阅读器,因此,我们来看一下 RSS 阅读器需要实现哪些功能。然后逐步完善重要的组件以实现 XML 处理并呈现到 Android 平台。完成这些任务后,您将拥有一个具有基本功能的 RSS 阅读器,并且具有一些功能钩子,可以在将来实现进一步扩展。

RSS 阅读器应用程序的主要需求以下各小节将详细介绍 Android RSS 阅读器是如何解决 RSS 阅读器应用程序的这些主要需求的。  指定感兴趣的 RSS 提要不计其数的 Internet 站点都提供 RSS 提要。应用程序需要指定要处理哪些 RSS 提要。一个功能丰富的 RSS 提要可以使用一种或多种方法选择所需的 RSS 提,包括能够从大量站点和通道中进行选择,或者允许用户在一个 EditView 中手动输入感兴趣的提要。为了尽量减少本教程中与非 XML 内容相关的代码,我们对 RSS 提要 URL 进行了硬编码。将菜单实现为一个钩子,以便根据需要添加 RSS 提要选择。获取感兴趣的 RSS 提要在对 RSS 提要进行任何解析和数据处理之前,首先需要从 Internet 中获得它。这意味着需要通过一个 Internet 连接(网络或 WiFi)连接到托管 RSS 提要的站点,然后执行一个 HTTP GET 操作检索 RSS 数据。返回的数据并不是文件形式,而是一个 XML 数据流。将使用 URL 类取回数据。解析 XML 数据流可以使用多种机制解析 XML 数据。这些机制都需要导航数据流并逐一描述各个数据元素,然后保存这些数据。Android SDK 提供了各种不同的 XML 解析器(Parser) ,但是您也可以选择自行创建。Android SDK 还提供了两种最流行的方法,即 DOM 解析器和 SAX 解析器。DOM 方法非常适合复杂的 XML 文档,因为它会在内存中构建面向节点的 XML 数据表示。SAX 方法在遇到新的标记时将使用回调,因而允许应用程序只保存感兴趣的数据。由于 RSS XML 结构的简单性,因此本教程将使用 SAX 解析器。本教程使用了一个 RSSHandler 类实现 SAX 解析器回调函数。保存 RSS 数据从 XML 数据流提取得到的 RSS 提要必须使用一种有用的格式保存。本教程使用了两个 helper 类:RSSFeed 和 RSSItem,它们将从 XML 数据流解析得到的数据保存到内存中。当 XML 数据流解析全部完成后,应用程序将与这些类进行交互以呈现信息。呈现 RSS 提要本教程的示例应用程序使用两个 Activity 类提供用户界面。主屏幕列出了 RSS 提要标题和发布日期,其后是一组 RSS 提要项。当通过一个 tap 选择某个提要项或将其输入 Android Emulator 后,ShowDescription 活动将显示有关该提要项的完整信息,包括它的标题(Title)、发布日期(Publication Date)、描述(Description)和链接(Link)元素。将设置一个用户界面,因此,文本中包含的任何链接如电子邮件或 Web 都处于激活状态 — 如果选择它们,将会发生相应的操作。例如,如果选择链接文本,将启动 Android 浏览器链接到该目标。通过这种方式,RSS 阅读器可以用非常直观的方式访问所有三种级别的信息。这就是 RSS 的强大之处,更具体地说,这就是 RSS 在移动平台中的功能。数据刷新和离线查看定期刷新数据是 RSS 阅读器的一个重要方面,另一个重要功能就是能够在离线时访问信息,例如当您在飞机上,您的 Android 设备处于飞行模式时。本教程的示例应用程序实现了一些这方面的功能,比如一个用于刷新数据的菜单钩子,但是本教程没有讨论数据持久性和调度功能。接下来将构建一个应用程序,获取一个 RSS 提要并在 Android 应用程序中显示。构建应用程序本教程后面的内容将帮助您构建一个 Android RSS 阅读器,主要分两部分讲述。第一部分介绍如何处理 XML 数据流,第二部分站点介绍如何在 Android 用户界面中呈现 RSS 数据。使用 SAX 获取并解析 XML 数据构建 RSS 阅读器应用程序的核心操作是获取并处理 XML 数据。我们将通过一个 Internet 连接和一个 HTTP GET 操作获取 XML 数据。可以使用 Java 中的一些不同的��实现这种 HTTP 处理。本教程演示了如何使用一个 URL 类的实例取回数据。如前面有关应用程序架构的小节所述,本教程将使用 SAX 解析器。如果数据格式相对简单,或者您的数据需求允许选择性地使用数据结构,那么使用 SAX 解析器仅需要最少量的内存和 excel。在深入研究 SAX 解析器的具体应用之前,请首先快速查看一下 RSSFeed 和 RSSItem 类,因为本教程后面的内容将大量提到这两个类。



RSSFeedRSSFeed 类从一个较高级别的角度表示 RSS 提要。RSSFeed 类包含 RSS 数据源的通道部分中感兴趣的元素,还包含一组RSSItem。RSSItem 表示 RSS 通道中的单个项。观察一下这两个重要的类。RSSFeed.java 如清单 4 所示。
清单 4. RSSFeed.java

  1. package com.msi.androidrss;
  2. import java.util.List;
  3. import java.util.Vector;
  4. import com.msi.androidrss.RSSItem;
  5. public class RSSFeed 
  6. {
  7.       private String _title = null;
  8.       private String _pubdate = null;
  9.       private int _itemcount = 0;
  10.       private List<RSSItem> _itemlist;
  11.       
  12.       
  13.       RSSFeed()
  14.       {
  15.             _itemlist = new Vector(0); 
  16.       }
  17.       int addItem(RSSItem item)
  18.       {
  19.             _itemlist.add(item);
  20.             _itemcount++;
  21.             return _itemcount;
  22.       }
  23.       RSSItem getItem(int location)
  24.       {
  25.             return _itemlist.get(location);
  26.       }
  27.       List getAllItems()
  28.       {
  29.             return _itemlist;
  30.       }
  31.       int getItemCount()
  32.       {
  33.             return _itemcount;
  34.       }
  35.       void setTitle(String title)
  36.       {
  37.             _title = title;
  38.       }
  39.       void setPubDate(String pubdate)
  40.       {
  41.             _pubdate = pubdate;
  42.       }
  43.       String getTitle()
  44.       {
  45.             return _title;
  46.       }
  47.       String getPubDate()
  48.       {
  49.             return _pubdate;
  50.       }
  51. }

复制代码



当 SAX 解析引擎在 RSS 源中完成了 XML 数据解析后,将创建一个 RSSFeed 类的实例,现在它包含了在您的应用程序中处理 RSS 数据所需的所有内容。RSSFeed 类包含三个重要元素,以及用于数据处理的 Set-ers 和 Get-ers。这些感兴趣的数据元素包括:

  • Title (_title):使用一个 Java.lang.String 保存通道的标题以便进行显示。
  • Publication Date (_pubdate):使用一个 java.lang.String 保存发布日期以便进行显示。注意,在更复杂的 RSS 阅读器中,您可以使用发布日期信息执行智能更新或刷新操作。
  • List of Items (_itemlist):一个参数化的 java.util.List,用于保存 RSSItem 集合。





RSSItem让我们看一看 RSSFeed 中包含的项列表。该列表中的每个元素都属于 RSSItem 类型。RSSItem 类定义了一些 java.lang.String 类型来保存解析器获得的值。将每个元素放入一个方便的检索类中,这使应用程序逻辑和用户界面的呈现变成了一个非常简单的任务,您稍后就会体会到。RSSItem.java 如清单 5 所示。
清单 5. RSSItem.java

  1. package com.msi.androidrss;
  2. public class RSSItem 
  3. {
  4.       private String _title = null;
  5.       private String _description = null;
  6.       private String _link = null;
  7.       private String _category = null;
  8.       private String _pubdate = null;
  9.       
  10.       
  11.       RSSItem()
  12.       {
  13.       }
  14.       void setTitle(String title)
  15.       {
  16.             _title = title;
  17.       }
  18.       void setDescription(String description)
  19.       {
  20.             _description = description;
  21.       }
  22.       void setLink(String link)
  23.       {
  24.             _link = link;
  25.       }
  26.       void setCategory(String category)
  27.       {
  28.             _category = category;
  29.       }
  30.       void setPubDate(String pubdate)
  31.       {
  32.             _pubdate = pubdate;
  33.       }
  34.       String getTitle()
  35.       {
  36.             return _title;
  37.       }
  38.       String getDescription()
  39.       {
  40.             return _description;
  41.       }
  42.       String getLink()
  43.       {
  44.             return _link;
  45.       }
  46.       String getCategory()
  47.       {
  48.             return _category;
  49.       }
  50.       String getPubDate()
  51.       {
  52.             return _pubdate;
  53.       }
  54.       public String toString()
  55.       {
  56.             // limit how much text you display
  57.             if (_title.length() > 42)
  58.             {
  59.                   return _title.substring(0, 42) + "...";
  60.             }
  61.             return _title;
  62.       }
  63. }

复制代码


RSSItem 类的实例包含与 RSS 提要中单个项有关的文本数据元素。除了用于保存数据的 java.lang.String 字段外,该类还为每个字段包含了一个 Get-er 和 Set-er。最后,该类覆盖了 toString() 方法,因为当 Android 用户界面元素显示项列表时将调用这个方法。请牢记关于 toString() 方法的注释,因为在讨论在 Android 用户界面呈现 RSS 数据时将使用到。





SAX 方法如上文所述,使用 SAX 方法解析 XML 依赖一种回调结构,在这种结构中,解析器将扫描数据流以查找标记,并在处理程序(由您提供)中调用方法来处理数据。该处理程序扩展了一个称为 DefaultHandler 的 Java 类。处理程序中有五种相关的方法。在 XML 解析处理中,每种方法都执行一个单独的、截然不同的重要角色。这五种方法分别是:
  • startDocument:当开始解析文档时调用。它将初始化所需的数���结构。
  • endDocument:在结束文档解析时调用。
  • startElement:当扫描器发现一个新标记时调用。处理程序通常使用这个方法确定文档中的位置,以便为保存数据做好准备。此外,与该元素相关的任何属性都可用于处理、保存和解释。
  • endElement:当扫描器遇到一个结束标记时调用。处理程序通常使用这种方法判断文档位置并保存中间过程产生的数据。在 RSS 示例应用程序中,当遇到 </item> 标记时,每个 RSSItem 被保存到 RSSFeed 对象。
  • characters:当标记中的数据变为可用时调用。例如,在解析 XML 数据时,标题、描述、链接、类别和发布日期元素的内容都被保存在这个方法中。



RSSHandlerRSSHandler 类是运行本教程应用程序的关键。它负责识别并保存 XML 数据流中的有关信息。当 SAX 解析器调用时,将依次调用它的每个方法。RSSHandler 实现一些非常基本的状态处理,从而在 SAX 解析器处理 XML 数据流时正确地识别和保存数据。SAX 方法可以使用多种正确的方式管理状态。虽然与本教程介绍的 RSS 提要解析主题没有必然联系,但是,如果您觉得在解析某一特定 XML 数据源时,使用 SAX 管理状态非常复杂,则可以考虑使用 DOM 解析器。DOM 解析器的工作前提是文档中的所有元素都非常重要,并且您的应用程序需要检测并提取 XML 数据源中的各种元素。SAX 非常适合 RSS 提要,因为 RSS 的关系非常简单。清单 6 展示了 RSSHandler.java 的实现。请迅速查看一下这些方法,以熟悉处理程序的结构。
清单 6. RSSHandler.java

  1. package com.msi.androidrss;
  2. import org.xml.sax.helpers.DefaultHandler;
  3. import org.xml.sax.*;
  4. import android.util.Log;
  5. public class RSSHandler extends DefaultHandler 
  6. {
  7.       
  8.       RSSFeed _feed;
  9.       RSSItem _item;
  10.       String _lastElementName = "";
  11.       boolean bFoundChannel = false;
  12.       final int RSS_TITLE = 1;
  13.       final int RSS_LINK = 2;
  14.       final int RSS_DESCRIPTION = 3;
  15.       final int RSS_CATEGORY = 4;
  16.       final int RSS_PUBDATE = 5;
  17.       
  18.       int depth = 0;
  19.       int currentstate = 0;
  20.       
  21.       RSSHandler()
  22.       {
  23.       }
  24.       
  25.       
  26.       RSSFeed getFeed()
  27.       {
  28.             return _feed;
  29.       }
  30.       
  31.       
  32.       public void startDocument() throws SAXException
  33.       {
  34.             // initialize our RSSFeed object - this will hold our parsed contents
  35.             _feed = new RSSFeed();
  36.             // initialize the RSSItem object - you will use this as a crutch to grab 
  37.             // the info from the channel
  38.             // because the channel and items have very similar entries..
  39.             _item = new RSSItem();
  40.             
  41.       }
  42.       public void endDocument() throws SAXException
  43.       {
  44.       }
  45.       public void startElement(String namespaceURI, String localName,String qName, 
  46.       Attributes atts) throws SAXException
  47.       {
  48.             depth++;
  49.             if (localName.equals("channel"))
  50.             {
  51.                   currentstate = 0;
  52.                   return;
  53.             }
  54.             if (localName.equals("image"))
  55.             {
  56.                   // record our feed data - you temporarily stored it in the item :)
  57.                   _feed.setTitle(_item.getTitle());
  58.                   _feed.setPubDate(_item.getPubDate());
  59.             }
  60.             if (localName.equals("item"))
  61.             {
  62.                   // create a new item
  63.                   _item = new RSSItem();
  64.                   return;
  65.             }
  66.             if (localName.equals("title"))
  67.             {
  68.                   currentstate = RSS_TITLE;
  69.                   return;
  70.             }
  71.             if (localName.equals("description"))
  72.             {
  73.                   currentstate = RSS_DESCRIPTION;
  74.                   return;
  75.             }
  76.             if (localName.equals("link"))
  77.             {
  78.                   currentstate = RSS_LINK;
  79.                   return;
  80.             }
  81.             if (localName.equals("category"))
  82.             {
  83.                   currentstate = RSS_CATEGORY;
  84.                   return;
  85.             }
  86.             if (localName.equals("pubDate"))
  87.             {
  88.                   currentstate = RSS_PUBDATE;
  89.                   return;
  90.             }
  91.             // if you don't explicitly handle the element, make sure you don't wind 
  92.             // up erroneously storing a newline or other bogus data into one of our 
  93.             // existing elements
  94.             currentstate = 0;
  95.       }
  96.       
  97.       public void endElement(String namespaceURI, String localName, String qName) 
  98.       throws SAXException
  99.       {
  100.             depth--;
  101.             if (localName.equals("item"))
  102.             {
  103.                   // add our item to the list!
  104.                   _feed.addItem(_item);
  105.                   return;
  106.             }
  107.       }
  108.       
  109.       public void characters(char ch[], int start, int length)
  110.       {
  111.             String theString = new String(ch,start,length);
  112.             Log.i("RSSReader","characters[" + theString + "]");
  113.             
  114.             switch (currentstate)
  115.             {
  116.                   case RSS_TITLE:
  117.                   _item.setTitle(theString);
  118.                   currentstate = 0;
  119.                   break;
  120.                   case RSS_LINK:
  121.                   _item.setLink(theString);
  122.                   currentstate = 0;
  123.                   break;
  124.                   case RSS_DESCRIPTION:
  125.                   _item.setDescription(theString);
  126.                   currentstate = 0;
  127.                   break;
  128.                   case RSS_CATEGORY:
  129.                   _item.setCategory(theString);
  130.                   currentstate = 0;
  131.                   break;
  132.                   case RSS_PUBDATE:
  133.                   _item.setPubDate(theString);
  134.                   currentstate = 0;
  135.                   break;
  136.                   default:
  137.                   return;
  138.             }
  139.             
  140.       }
  141. }

复制代码





赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论