Android Rss阅读器

前言

        前几天去北京面试,题目是让我解析一下腾讯的Rss。之前虽然知道xml,但是自己从来没有去学习怎么解析,在网上查一些例子,但是就是没有解析出来。现在看看还蛮好笑的,因为我那时候是使用sax解析xml的,可不巧的是让我解析的xml的encoding是“GBK”,但是sax默认使用utf-8。所以没有解析出来也是对于sax不熟悉导致的了。关于如何解决这个问题下面会说。


Rss概念

      要在Android平台中开发RSS客户端,首先需要了解什么是RSS,RSS怎样工作,及怎样解析XML等知识。

      首先,我们必须要了解什么是RSS:

       1. RSS指Really Simple Syndication(真正简易联合)

       2. RSS使您有能力聚合(syndicate)网站的内容

       3. RSS定义了非常简单的方法来共享和查看标题和内容

       4. RSS文件可被自动更新

       5. RSS允许为不同的网站进行视图的个性化

       6. RSS使用XML编写

       RSS被设计用来展示选定的数据。如果没有 RSS,用户就不得不每日都来您的网站检查新的内容。对许多用户来说这样太费时了。通过RSS feed(RSS 通常被称为 News feed 或 RSS feed),用户们可以使用 RSS 聚合器来更快地检查您的网站更新(RSS 聚合器是用来聚集并分类 RSS feed 的网站或软件)。由于RSS 数据很小巧并可快速加载,它可轻易地被类似移动电话或 PDA 的服务使用。拥有相似内容的网站环(Web-rings)可以轻易地在它们的网站共享内容,使这些网站更出色更有价值。

       谁应当使用RSS?

       那些极少更新内容的网管们不需要RSS!

       RSS对那些频繁更新内容的网站是很有帮助的,比如:

       新闻站点          列出新闻的标题、日期以及描述

       企业                 列出新闻和新产品

       日程表             列出即将来临的安排和重要日期

       站点更新         列出更新过的页面或新的页面

       RSS如何工作

       使用RSS,您在名为聚合器的公司注册您的内容。

       步骤之一是,创建一个RSS 文档,然后使用.xml 后缀来保存它。然后把此文件上传到您的网站。接下来,通过一个RSS 聚合器来注册。每天,聚合器都会到被注册的网站搜索RSS文档,校验其链接,并显示有关 feed 的信息,这样客户就能够链接到使他们产生兴趣的文档。

       一个RSS实例文档


       RSS文档使用一种简单的自我描述的语法: 让我们看一个简单的RSS文档:

[java]  view plain copy
  1. <?xml version="1.0" encoding="ISO-8859-1" ?>    
  2. <rss version="2.0">    
  3.     
  4. <channel>    
  5.   <title>W3School Home Page</title>    
  6.   <link>http://www.w3school.com.cn</link>    
  7.   <description>Free web building tutorials</description>    
  8.   <item>    
  9.     <title>RSS Tutorial</title>    
  10.     <link>http://www.w3school.com.cn/rss</link>    
  11.     <description>New RSS tutorial on W3School</description>    
  12.   </item>    
  13.   <item>    
  14.     <title>XML Tutorial</title>    
  15.     <link>http://www.w3school.com.cn/xml</link>    
  16.     <description>New XML tutorial on W3School</description>    
  17.   </item>    
  18. </channel>    
  19.     
  20. </rss>    
       文档中的第一行:XML声明 - 定义了文档中使用的XML 版本和字符编码。此例子遵守1.0规范,并使用ISO-8859-1 (Latin-1/West European) 字符集。


       下一行是标识此文档是一个RSS文档的RSS 声明(此例是 RSS version 2.0)。

       下一行含有 <channel> 元素。此元素用于描述RSS feed。

       <channel> 元素有三个必需的子元素:

                 <title> - 定义频道的标题。(比如 w3school 首页)

                 <link> - 定义到达频道的超链接。(比如:www.w3school.com.cn)

                 <description> - 描述此频道(比如免费的网站建设教程)

       每个<channel>元素可拥有一个或多个 <item> 元素。

       每个<item>元素可定义 RSS feed 中的一篇文章或 "story"。

       <item> 元素拥有三个必需的子元素:

                 <title> - 定义项目的标题。(比如 RSS 教程)

                 <link> - 定义到达项目的超链接。(比如:http://www.w3school.com.cn/rss)

                 <description> - 描述此项目(比如 w3school 的RSS 教程)

       最后,后面的两行关闭 <channel> 和 <rss> 元素。

       上面的只是是一个例子,下面来看一下实际应用的Rss:

[java]  view plain copy
  1. <?xml version="1.0" encoding="gb2312"?>  
  2.   
  3.   
  4. <?xml-stylesheet type="text/xsl" href="/css/rss_xml_style.css"?>  
  5.   
  6. <rss version="2.0">  
  7.   <channel>  
  8.     <title>新闻国内</title>  
  9.     <image>  
  10.       <title>新闻国内</title>  
  11.       <link>http://news.qq.com</link>  
  12.       <url>http://mat1.qq.com/news/rss/logo_news.gif</url>  
  13.     </image>  
  14.     <description>新闻国内</description>  
  15.     <link>http://news.qq.com/china_index.shtml</link>  
  16.     <copyright>Copyright 1998 - 2005 TENCENT Inc. All Rights Reserved</copyright>  
  17.     <language>zh-cn</language>  
  18.     <generator>www.qq.com</generator>  
  19.     <item>  
  20.       <title>浙江温州泰顺广播电视台原台长受贿获刑十年</title>  
  21.       <link>http://news.qq.com/a/20130608/012227.htm</link>  
  22.       <author>www.qq.com</author>  
  23.       <category/>  
  24.       <pubDate>2013-06-08 12:05:21</pubDate>  
  25.       <comments/>  
  26.       <description>  中新网温州68日电(记者赵小燕通讯员晨翔)利用担任广播电视台台长的职务便利,在产品采购、干部任用、人事调动、人事招录等方面为他人谋取利益,先后收受许某某等人所送共计284200元。近日,温州泰顺县人民法院以受贿罪判处被告人张某某有期徒刑十年,并处没收财产30000元;没收被告人张某某受贿违法所得284200元,上</description>  
  27.     </item>  
  28.     <item>  
  29.       <title>河南新蔡回应开发商违规 对外界质疑只字不提</title>  
  30.       <link>http://news.qq.com/a/20130608/012148.htm</link>  
  31.       <author>www.qq.com</author>  
  32.       <category/>  
  33.       <pubDate>2013-06-08 11:59:42</pubDate>  
  34.       <comments/>  
  35.       <description>中新网驻马店68日电(记者侯伟胜)本网对河南省新蔡县“城市1号工程”伟利国际广场在征地、施工、销售等环节涉嫌违规一事进行报道后,引起广泛关注。67日下午,新蔡县国土局以电子邮件的形式对报道内容进行了说明。但是对于群众最为关注的几点质疑,却只字未提。伟利国际广场是驻马店市、新蔡县重点招商引资项目,新蔡县</description>  
  36.     </item>  
       后面省略了很多item,大体看一下结构就可以。
        RSS中的注释

       在RSS 中书写注释的语法与HTML 的语法类似:

       <!-- This is an RSS comment -->

       RSS使用XML来编写

       因为RSS也是XML,请记住:

       1. 所有的元素必许拥有关闭标签

       2. 元素对大小写敏感

       3. 元素必需被正确地嵌套

       4. 属性值必须带引号

       以上内容来自http://www.w3school.com.cn/rss/index.asp,对RSS进行了简单讲解,如果想看更详细的内容可以去w3school看看。我们后面要讲的Android RSS客户端就是以此为基础完成的,所以掌握好RSS基础很重要。

   

Rss解析 

          了解了以上内容,我们就通过一个例子来学习RSS,如何对XML文件进行解析。首先,展示一下完成之后项目的运行结果: 

                                                

                                                

       下面是程序的具体实现

一:界面布局,具体代码如下: 

activity_main.xml:

[java]  view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <ListView   
  7.         android:id="@+id/list"   
  8.         android:cacheColorHint="#00000000"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent" />  
  11.       
  12. </RelativeLayout>  
activity_show_description.xml  :

[java]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/content"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:autoLink="web"  
  12.         android:text="" />  
  13.   
  14.     <Button  
  15.         android:ida="@+id/back"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_gravity="right"  
  19.         android:text="@string/back" />  
  20.   
  21. </LinearLayout>  
二:编写实体类RssFeed及RssItem

RssFeed.java:

[java]  view plain copy
  1. package com.example.rssnews.domain;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6.   
  7. public class RssFeed {  
  8.   
  9.     private String title; // 标题  
  10.     private String pubdate; // 发布日期  
  11.       
  12.     private int itemCount; // 用于计算列表的数目  
  13.     private List<RssItem> rssItems; // 用于描述列表item  
  14.   
  15.     public RssFeed() {  
  16.         rssItems = new ArrayList<RssItem>();  
  17.     }  
  18.   
  19.     // 添加RssItem条目,返回列表长度  
  20.     public int addItem(RssItem rssItem) {  
  21.         rssItems.add(rssItem);  
  22.         itemCount++;  
  23.         return itemCount;  
  24.     }  
  25.   
  26.     // 根据下标获取RssItem  
  27.     public RssItem getItem(int position) {  
  28.         return rssItems.get(position);  
  29.     }  
  30.   
  31.     public List<HashMap<String, Object>> getAllItems() {  
  32.         List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();  
  33.         for (int i = 0; i < rssItems.size(); i++) {  
  34.             HashMap<String, Object> item = new HashMap<String, Object>();  
  35.             item.put(RssItem.TITLE, rssItems.get(i).getTitle());  
  36.             item.put(RssItem.PUBDATE, rssItems.get(i).getPubdate());  
  37.             data.add(item);  
  38.         }  
  39.         return data;  
  40.   
  41.     }  
  42.   
  43.     public String getTitle() {  
  44.         return title;  
  45.     }  
  46.   
  47.     public void setTitle(String title) {  
  48.         this.title = title;  
  49.     }  
  50.   
  51.     public String getPubdate() {  
  52.         return pubdate;  
  53.     }  
  54.   
  55.     public void setPubdate(String pubdate) {  
  56.         this.pubdate = pubdate;  
  57.     }  
  58.   
  59.     public int getItemCount() {  
  60.         return itemCount;  
  61.     }  
  62.   
  63.     public void setItemCount(int itemCount) {  
  64.         this.itemCount = itemCount;  
  65.     }  
  66.   
  67. }  
RssItem.java:

[java]  view plain copy
  1. package com.example.rssnews.domain;  
  2.   
  3. public class RssItem {  
  4.   
  5.     private String title;  
  6.     private String link;  
  7.     private String author;  
  8.     private String category;  
  9.     private String pubdate;  
  10.     private String comments;  
  11.     private String description;  
  12.   
  13.     public static final String TITLE = "title";  
  14.     public static final String PUBDATE = "pubdate";  
  15.   
  16.     public RssItem() {  
  17.   
  18.     }  
  19.   
  20.     public String getTitle() {  
  21.         if (title.length() > 20) {  
  22.             return title.substring(019) + "...";  
  23.         }  
  24.         return title;  
  25.     }  
  26.   
  27.     public void setTitle(String title) {  
  28.         this.title = title;  
  29.     }  
  30.   
  31.     public String getDescription() {  
  32.         return description;  
  33.     }  
  34.   
  35.     public void setDescription(String description) {  
  36.         this.description = description;  
  37.     }  
  38.   
  39.     public String getLink() {  
  40.         return link;  
  41.     }  
  42.   
  43.     public void setLink(String link) {  
  44.         this.link = link;  
  45.     }  
  46.   
  47.     public String getCategory() {  
  48.         return category;  
  49.     }  
  50.   
  51.     public void setCategory(String category) {  
  52.         this.category = category;  
  53.     }  
  54.   
  55.     public String getPubdate() {  
  56.         return pubdate;  
  57.     }  
  58.   
  59.     public void setPubdate(String pubdate) {  
  60.         this.pubdate = pubdate;  
  61.     }  
  62.   
  63.     public String getComments() {  
  64.         return comments;  
  65.     }  
  66.   
  67.     public void setComments(String comments) {  
  68.         this.comments = comments;  
  69.     }  
  70.       
  71.     public String getAuthor() {  
  72.         return author;  
  73.     }  
  74.   
  75.     public void setAuthor(String author) {  
  76.         this.author = author;  
  77.     }  
  78.       
  79.     @Override  
  80.     public String toString() {  
  81.         return "RssItem [title=" + title + ", description=" + description  
  82.                 + ", link=" + link + ", category=" + category + ", pubdate="  
  83.                 + pubdate + "]";  
  84.     }  
  85.   
  86. }  
三:编写解析XML文件时的处理类,用自定义的RssHandler继承自DefaultHandler,然后重载DefaultHandler的五个方法。具体代码如下:

RssHandler.java:

[java]  view plain copy
  1. package com.example.rssnews.util;  
  2.   
  3. import org.xml.sax.Attributes;  
  4. import org.xml.sax.SAXException;  
  5. import org.xml.sax.helpers.DefaultHandler;  
  6. import com.example.rssnews.domain.RssFeed;  
  7. import com.example.rssnews.domain.RssItem;  
  8. import android.util.Log;  
  9.   
  10. public class RssHandler extends DefaultHandler {  
  11.   
  12.     RssFeed rssFeed;  
  13.     RssItem rssItem;  
  14.   
  15.     String lastElementName = "";// 标记变量,用于标记在解析过程中我们关心的几个标签,若不是我们关心的标签记做0  
  16.   
  17.     final int RSS_TITLE = 1;// 若是 title 标签,记做1,注意有两个title,但我们都保存在item的成员变量中  
  18.     final int RSS_LINK = 2;// 若是 link 标签,记做2  
  19.     final int RSS_AUTHOR = 3;  
  20.     final int RSS_CATEGORY = 4;// 若是category标签,记做 4  
  21.     final int RSS_PUBDATE = 5// 若是pubdate标签,记做5,注意有两个pubdate,但我们都保存在item的pubdate成员变量中  
  22.     final int RSS_COMMENTS = 6;  
  23.     final int RSS_DESCRIPTION = 7;// 若是 description 标签,记做3  
  24.   
  25.     int currentFlag = 0;  
  26.   
  27.     public RssHandler() {  
  28.   
  29.     }  
  30.   
  31.     @Override  
  32.     public void startDocument() throws SAXException {  
  33.         super.startDocument();  
  34.         rssFeed = new RssFeed();  
  35.         rssItem = new RssItem();  
  36.   
  37.     }  
  38.   
  39.     @Override  
  40.     public void characters(char[] ch, int start, int length)  
  41.             throws SAXException {  
  42.         super.characters(ch, start, length);  
  43.         // 获取字符串  
  44.         String text = new String(ch, start, length);  
  45.         Log.i("i""要获取的内容:" + text);  
  46.   
  47.         switch (currentFlag) {  
  48.         case RSS_TITLE:  
  49.             rssItem.setTitle(text);  
  50.             currentFlag = 0;// 设置完后,重置为开始状态  
  51.             break;  
  52.         case RSS_PUBDATE:  
  53.             rssItem.setPubdate(text);  
  54.             currentFlag = 0;// 设置完后,重置为开始状态  
  55.             break;  
  56.         case RSS_CATEGORY:  
  57.             rssItem.setCategory(text);  
  58.             currentFlag = 0;// 设置完后,重置为开始状态  
  59.             break;  
  60.         case RSS_LINK:  
  61.             rssItem.setLink(text);  
  62.             currentFlag = 0;// 设置完后,重置为开始状态  
  63.             break;  
  64.         case RSS_AUTHOR:  
  65.             rssItem.setAuthor(text);  
  66.             currentFlag = 0;// 设置完后,重置为开始状态  
  67.             break;  
  68.         case RSS_DESCRIPTION:  
  69.             rssItem.setDescription(text);  
  70.             currentFlag = 0;// 设置完后,重置为开始状态  
  71.             break;  
  72.         case RSS_COMMENTS:  
  73.             rssItem.setComments(text);  
  74.             currentFlag = 0;// 设置完后,重置为开始状态  
  75.             break;  
  76.         default:  
  77.             break;  
  78.         }  
  79.     }  
  80.   
  81.     @Override  
  82.     public void startElement(String uri, String localName, String qName,  
  83.             Attributes attributes) throws SAXException {  
  84.         super.startElement(uri, localName, qName, attributes);  
  85.         if ("chanel".equals(localName)) {  
  86.             // 这个标签内没有我们关心的内容,所以不作处理,currentFlag=0  
  87.             currentFlag = 0;  
  88.             return;  
  89.         }  
  90.         if ("item".equals(localName)) {  
  91.             rssItem = new RssItem();  
  92.             return;  
  93.         }  
  94.         if ("title".equals(localName)) {  
  95.             currentFlag = RSS_TITLE;  
  96.             return;  
  97.         }  
  98.         if ("description".equals(localName)) {  
  99.             currentFlag = RSS_DESCRIPTION;  
  100.             return;  
  101.         }  
  102.         if ("link".equals(localName)) {  
  103.             currentFlag = RSS_LINK;  
  104.             return;  
  105.         }  
  106.         if ("pubDate".equals(localName)) {  
  107.             currentFlag = RSS_PUBDATE;  
  108.             return;  
  109.         }  
  110.         if ("category".equals(localName)) {  
  111.             currentFlag = RSS_CATEGORY;  
  112.             return;  
  113.         }  
  114.   
  115.         if ("author".equals(localName)) {  
  116.             currentFlag = RSS_AUTHOR;  
  117.             return;  
  118.         }  
  119.           
  120.         if ("comments".equals(localName)) {  
  121.             currentFlag = RSS_COMMENTS;  
  122.             return;  
  123.         }  
  124.     }  
  125.   
  126.     @Override  
  127.     public void endElement(String uri, String localName, String qName)  
  128.             throws SAXException {  
  129.         super.endElement(uri, localName, qName);  
  130.         // 如果解析一个item节点结束,就将rssItem添加到rssFeed中。  
  131.         if ("item".equals(localName)) {  
  132.   
  133.             rssFeed.addItem(rssItem);  
  134.             return;  
  135.         }  
  136.     }  
  137.   
  138.     @Override  
  139.     public void endDocument() throws SAXException {  
  140.         super.endDocument();  
  141.     }  
  142.   
  143.     public RssFeed getRssFeed() {  
  144.         return rssFeed;  
  145.     }  
  146.   
  147. }  
四: 从SAXParser解析器中获得解析xml文件的xmlReader ,使用三中自定义的xml解析器作为xmlReader的处理器,然后使用url打开流,并将流作为 xmlReader解析的输入源并解析。这里需要注意Rss的编码格式,做一个处理。具体代码如下:
[java]  view plain copy
  1. package com.example.rssnews.util;  
  2.   
  3. import info.monitorenter.cpdetector.io.ASCIIDetector;  
  4. import info.monitorenter.cpdetector.io.CodepageDetectorProxy;  
  5. import info.monitorenter.cpdetector.io.JChardetFacade;  
  6. import info.monitorenter.cpdetector.io.ParsingDetector;  
  7. import info.monitorenter.cpdetector.io.UnicodeDetector;  
  8. import java.io.IOException;  
  9. import java.io.InputStream;  
  10. import java.io.InputStreamReader;  
  11. import java.net.URL;  
  12. import java.nio.charset.Charset;  
  13. import javax.xml.parsers.ParserConfigurationException;  
  14. import javax.xml.parsers.SAXParser;  
  15. import javax.xml.parsers.SAXParserFactory;  
  16. import org.xml.sax.InputSource;  
  17. import org.xml.sax.SAXException;  
  18. import org.xml.sax.XMLReader;  
  19. import com.example.rssnews.domain.RssFeed;  
  20.   
  21. public class RssFeed_SAXParser {  
  22.   
  23.     public RssFeed getFeed(String urlStr) throws ParserConfigurationException,  
  24.             SAXException, IOException {  
  25.         URL url = new URL(urlStr);  
  26.         SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // 构建SAX解析工厂  
  27.         SAXParser saxParser = saxParserFactory.newSAXParser(); // 解析工厂生产解析器  
  28.         XMLReader xmlReader = saxParser.getXMLReader(); // 通过saxParser构建xmlReader阅读器  
  29.   
  30.         RssHandler rssHandler = new RssHandler();  
  31.         xmlReader.setContentHandler(rssHandler);  
  32.         // 使用url打开流,并将流作为 xmlReader解析的输入源并解析  
  33.   
  34.         CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();  
  35.         // 向代理对象添加探测器  
  36.         detector.add(JChardetFacade.getInstance());  
  37.         // 得到编码字符集对象  
  38.         Charset charset = detector.detectCodepage(url);  
  39.         // 得到编码名称  
  40.         String encodingName = charset.name();  
  41.         System.out.println(encodingName);  
  42.   
  43.         InputSource inputSource = null;  
  44.         InputStream stream = null;  
  45.   
  46.         // 如果是GB2312编码  
  47.         if ("GBK".equals(encodingName)) {  
  48.             stream = url.openStream();  
  49.             // 通过InputStreamReader设定编码方式  
  50.             InputStreamReader streamReader = new InputStreamReader(stream,  
  51.                     encodingName);  
  52.             inputSource = new InputSource(streamReader);  
  53.             xmlReader.parse(inputSource);  
  54.             return rssHandler.getRssFeed();  
  55.         } else {  
  56.             // 是utf-8编码  
  57.             inputSource = new InputSource(url.openStream());  
  58.             inputSource.setEncoding("UTF-8");  
  59.             xmlReader.parse(inputSource);  
  60.             return rssHandler.getRssFeed();  
  61.         }  
  62.     }  
  63.   
  64.     /** 
  65.      * 获得远程URL文件的编码格式 
  66.      */  
  67.     public static String getReomoteURLFileEncode(URL url) {  
  68.   
  69.         CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();  
  70.         detector.add(new ParsingDetector(false));  
  71.         detector.add(JChardetFacade.getInstance());  
  72.         detector.add(ASCIIDetector.getInstance());  
  73.         detector.add(UnicodeDetector.getInstance());  
  74.         java.nio.charset.Charset charset = null;  
  75.         try {  
  76.             System.out.println(url);  
  77.             charset = detector.detectCodepage(url);  
  78.         } catch (Exception ex) {  
  79.             ex.printStackTrace();  
  80.         }  
  81.         if (charset != null) {  
  82.             return charset.name();  
  83.         } else {  
  84.             return "utf-8";  
  85.         }  
  86.     }  
  87. }  
五:编写MainActivity,将解析的XML文件以列表的形式显示出来,具体代码如下:

MainActivity.java:

[java]  view plain copy
  1. package com.example.rssnews;  
  2.   
  3. import java.io.IOException;  
  4. import javax.xml.parsers.ParserConfigurationException;  
  5. import org.xml.sax.SAXException;  
  6. import com.example.rssnews.domain.RssFeed;  
  7. import com.example.rssnews.domain.RssItem;  
  8. import com.example.rssnews.util.RssFeed_SAXParser;  
  9. import android.os.Bundle;  
  10. import android.app.Activity;  
  11. import android.content.Intent;  
  12. import android.view.Menu;  
  13. import android.view.View;  
  14. import android.widget.AdapterView;  
  15. import android.widget.AdapterView.OnItemClickListener;  
  16. import android.widget.ListView;  
  17. import android.widget.SimpleAdapter;  
  18.   
  19. public class MainActivity extends Activity implements OnItemClickListener {  
  20.   
  21.     // 从网络获取RSS地址  
  22.     public final String RSS_URL = "http://news.qq.com/newsgn/rss_newsgn.xml";  
  23.   
  24.     public final String tag = "RSSReader";  
  25.     private RssFeed feed = null;  
  26.   
  27.     @Override  
  28.     public void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_main);  
  31.         try {  
  32.             feed = new RssFeed_SAXParser().getFeed(RSS_URL);  
  33.             System.out.println(feed.getAllItems());  
  34.         } catch (ParserConfigurationException e) {  
  35.             e.printStackTrace();  
  36.         } catch (SAXException e) {  
  37.             e.printStackTrace();  
  38.         } catch (IOException e) {  
  39.             e.printStackTrace();  
  40.         }  
  41.         showListView();  
  42.     }  
  43.   
  44.     /* 
  45.      * 把RSS内容绑定到ui界面进行显示 
  46.      */  
  47.     private void showListView() {  
  48.   
  49.         ListView itemList = (ListView) this.findViewById(R.id.list);  
  50.         if (feed == null) {  
  51.             setTitle("访问的RSS无效");  
  52.             return;  
  53.         }  
  54.         SimpleAdapter simpleAdapter = new SimpleAdapter(this,  
  55.                 feed.getAllItems(), android.R.layout.simple_list_item_2,  
  56.                 new String[] { RssItem.TITLE, RssItem.PUBDATE }, new int[] {  
  57.                         android.R.id.text1, android.R.id.text2 });  
  58.         itemList.setAdapter(simpleAdapter);  
  59.         itemList.setOnItemClickListener(this);  
  60.         itemList.setSelection(0);  
  61.     }  
  62.   
  63.     @Override  
  64.     public boolean onCreateOptionsMenu(Menu menu) {  
  65.         getMenuInflater().inflate(R.menu.main, menu);  
  66.         return true;  
  67.     }  
  68.   
  69.     @Override  
  70.     public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {  
  71.   
  72.         Intent intent = new Intent();  
  73.         intent.setClass(this, ShowDescriptionActivity.class);  
  74.         Bundle bundle = new Bundle();  
  75.         bundle.putString("title", feed.getItem(position).getTitle());  
  76.         bundle.putString("description",feed.getItem(position).getDescription());  
  77.         bundle.putString("link", feed.getItem(position).getLink());  
  78.         bundle.putString("pubdate", feed.getItem(position).getPubdate());  
  79.         // 用android.intent.extra.INTENT的名字来传递参数  
  80.         intent.putExtra("android.intent.extra.rssItem", bundle);  
  81.         startActivityForResult(intent, 0);  
  82.     }  
  83.   
  84. }  
编写ShowDescriptionActivity,用于显示每条新闻的详情,具体代码如下:

ShowDescriptionActivity.java:

[java]  view plain copy
  1. package com.example.rssnews;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.content.Intent;  
  6. import android.view.Menu;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.TextView;  
  11.   
  12. public class ShowDescriptionActivity extends Activity {  
  13.   
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_show_description);  
  18.         String content =null;  
  19.           
  20.         Intent intent = getIntent();  
  21.         if(intent!=null){  
  22.             Bundle bundle = intent.getBundleExtra("android.intent.extra.rssItem");  
  23.             if(bundle==null){  
  24.                 content = "不好意思程序出错啦";  
  25.             }else{  
  26.                 content = bundle.getString("title") + "nn"  
  27.                         + bundle.getString("pubdate") + "nn"  
  28.                         + bundle.getString("description").replace('n'' ')  
  29.                         + "nn详细信息请访问以下网址:n" + bundle.getString("link");  
  30.             }  
  31.         }else{  
  32.             content = "不好意思程序出错啦";  
  33.         }  
  34.           
  35.         TextView contentText = (TextView) this.findViewById(R.id.content);  
  36.         contentText.setText(content);  
  37.           
  38.         Button backButton = (Button) this.findViewById(R.id.back);  
  39.         backButton.setOnClickListener(new OnClickListener() {  
  40.               
  41.             @Override  
  42.             public void onClick(View v) {  
  43.                 finish();  
  44.             }  
  45.         });  
  46.     }  
  47.   
  48.     @Override  
  49.     public boolean onCreateOptionsMenu(Menu menu) {  
  50.         getMenuInflater().inflate(R.menu.main, menu);  
  51.         return true;  
  52.     }  
  53.   
  54. }  

最后,不要忘了在AndroidManifest.xml文件中添加访问网络的权限:<uses-permission android:name="android.permission.INTERNET"/>这样,自此一个简易的RSS阅读器就完成了,还有很多需要完善的地方,感兴趣的朋友可以在这个基础上进一步完善~相应的项目已上传至csdn资源中、欢迎下载

推荐阅读:

  1. http://www.ourunix.org/android/post/57.html
  2. http://architecture.riaos.com/?p=3003376
  3. http://www.ibm.com/developerworks/cn/education/xml/x-androidrss/section5.html
  4. http://www.jizhuomi.com/android/example/146.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值