前一阵子,一直在学Android开发。秉承着一贯的自学习惯,学一样东西就得实际自己做个小玩意玩玩。于是乎找到个Android构建RSS阅读器教程。总体来说内容不算太难,虽然有点outdated,但是不影响学习。后来将原代码下下来后运行竟然出错了,而且完全读不出RSS。我就纳闷了,这上面的东西难道写错了?
抱着怀疑的态度,我开始验证此代码。首先,Java上面的解析XML的方法大致有两种:SAX解析器、DOM解析器。为了简单起见SAX解析是个不错的选择。SAX解析的大致流程就是一个工厂设计模式,于此同时附带一些Handler作为事件处理机制,详情可以看看百度文库的一篇文章。以下是个例子:
抱着怀疑的态度,我开始验证此代码。首先,Java上面的解析XML的方法大致有两种:SAX解析器、DOM解析器。为了简单起见SAX解析是个不错的选择。SAX解析的大致流程就是一个工厂设计模式,于此同时附带一些Handler作为事件处理机制,详情可以看看百度文库的一篇文章。以下是个例子:
private RSSFeed getFeed(String urlToRssFeed)
{
try
{
// setup the url
URL url = new URL(urlToRssFeed);
// create the factory
SAXParserFactory factory = SAXParserFactory.newInstance();
// create a parser
SAXParser parser = factory.newSAXParser();
// create the reader (scanner)
XMLReader xmlreader = parser.getXMLReader();
// instantiate our handler
RSSHandler theRssHandler = new RSSHandler();
// assign our handler
xmlreader.setContentHandler(theRssHandler);
// get our data through the url class
InputSource is = new InputSource(url.openStream());
// perform the synchronous parse
xmlreader.parse(is);
// get the results - should be a fully populated RSSFeed instance,
// or null on error
return theRssHandler.getFeed();
}
catch (Exception ee)
{
// if you have a problem, simply return null
return null;
}
}
然后另一个要说的就是Handler了,关于Handler主要关注的一点就是就是这个函数接口
public void startElement(String namespaceURI, String localName,String qName, Attributes atts)
原文里用来区分标签类型的参数都是通过localName,但实际测试的过程中我发现这个参数根本就接收不到标签的信息而应该是qName,以下是我用Eclipse调试一条测试RSS的结果。
现在网上绝大多数流传两个版本:一个是使用qName检索的一个是localName检索的。但实际情况应该qName较为正确,虽然还会读出标签所属命名空间。这里是关于startElement()接口的介绍。虽然看的不是很明白,但是实际情况则是qName能够读到标签。
最后说个小细节,就是从网络上获取RSS的办法有很多,原文里面使用URL类来读取,当中有个小问题就是如果你操作系统正在翻墙(使用代理软件)的话,就会出现无法解析Host的异常。这还是我无意中发现的,解决方法你可以用Apache Commons的HttpClient库来写个代理方法读(java原生库不太会用,原理也是一样的吧,只不过Apache的会简单点),这样就OK了。
最后说个小细节,就是从网络上获取RSS的办法有很多,原文里面使用URL类来读取,当中有个小问题就是如果你操作系统正在翻墙(使用代理软件)的话,就会出现无法解析Host的异常。这还是我无意中发现的,解决方法你可以用Apache Commons的HttpClient库来写个代理方法读(java原生库不太会用,原理也是一样的吧,只不过Apache的会简单点),这样就OK了。