郑昀@ultrapower

产品名称

产品版本

Keyword: RssReader RssFeed Channel j2me midp midlet  kxml xmlpull RMS RssOwl java

RSS无线阅读器

0.7.1729

[J2ME][开源]RSSOwlMidlet

(RSS无线阅读器)

设计说明

我的RssReader资源:

1:《[J2ME]RSSOwlMidlet(RSS无线阅读器)开源说明》

2:《[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明》

3:下载源代码:http://files.cnblogs.com/zhengyun_ustc/RSSOwlMidlet-src.rar

4:下载midlet:jad: RSSOwlMidlet.jad jar: RSSOwlMidlet.jar (jar包可能有点偏大,您可以进行混淆来缩小)

摘要:

本文档给出RSS无线阅读器J2ME版本的设计思路和类说明。

第1章 简单描述RSS无线阅读器J2ME版本的背景、功能和特别之处。

第2章 描述调用RSS无线阅读器J2ME版本的设计思路。

第3章 给出了 RSS无线阅读器J2ME版本的设计过程中需要特别指出的问题。

第4章 给出了 各种下载资源。

 

1背景、功能和特别之处

摘要:本章 简单描述RSS无线阅读器J2ME版本的背景、功能和特别之处。

我们提供的RSS无线阅读器J2ME版本[开源]是一个可以下载到手机(例如Nokia7610)或者其他无线手持设备(例如PocketPC)的应用程序,用来阅读存在于Internet中广泛的RSS新闻源,比如

豆瓣最新评论 http://www.douban.com/feed/review/latest;

博客堂 http://blog.joycode.com/MainFeed.aspx;

博客园 http://www.cnblogs.com/rss.aspx;

CSDN技术文档 http://www.csdn.net/Rss/RssFeed.aspx?rssid=3;

ChinaUnix.net-业界新闻与评论 http://bbs.chinaunix.net/rss/46.xml;

keso's blog http://feeds.feedburner.com/PlayinWithIt

等等,这些新闻源我们将预置在本应用程序中。

下面介绍RSS无线阅读器的功能列表:

l         RSS Feed列表

n         添加Rss Feed

n         编辑Rss Feed

n         删除Rss Feed

l         读取Rss Feed新闻

n         查看新闻摘要

l         重新读取Rss Feed新闻

l         关于我

1.1. RSS概念

这里简单介绍一下RSS,它并不是一个新概念,从大约2002年就已经通行天下了,最通常的是Blog的RSS输出,当然许多其他类型的站点也都提供了本站内容的RSS输出格式,比如:

论坛帖子,比如“ChinaUnix.net”;

新闻站点,比如“百度新闻”或者“Google新闻”;

门户,比如“新浪体育”,等等。

RSS其实就是特定格式的XML。所以在J2ME解决方案中,就是通过HttpConnection获取RSS XML文档并解析,将新闻条目显示在界面上,说起来很简单的。

下面,我们说说这个应用程序的特别之处。

1.2. 特别之处

这个应用程序的思路来自于两个开源的应用程序:

How to create a J2ME MIDP RSS Reader application with NetBeans 4.0 作者 Tommi Laukkanen

J2ME手机电话本 作者 garrey

RSS读取以及用xmlpull解析这部分思路,采用了Tommi 的思路;

MVC的类分解,以及对RMS记录存储的封装模式,采用了 garrey 的思路。

对于获取RMS中存储的所有的Rss Feed列表,采用了文章《探索J2ME:对记录进行排序》的代码,放弃了garrey的RecordComparator比较器的实现。

另外,在调试过程中,也加入了我的一些思考,以及兼容各种RSS的办法。

总结一下特别之处。

特别是比原来Tommi 的版本增加了几个特性:

l         最大的改动就是,原来Tommi把视图/控制器都放在RssReaderMIDlet.java了,而我们将视图分拆出来为RssFeedAdd.javaRssFeedEdit.javaRssFeedList.java等等,控制器则为GUIController.java

l         可以添加/编辑/删除Rss Feed书签;

l         原来TommiFeed列表以及URL存储在RMS的一个条目,我放弃了这种做法,而是像garrey处理电话记录一样;

l         当请求远端服务器时,加入了动画等候画面,提示用户正在获取新闻列表;

l         由于采用了xmlpull方式解析XML,所以可以做到一边后台扫描XML文档,一边前台将解析到的新闻Title显示在用户界面上,不影响用户阅读新闻列表;

l         兼容博客堂/博客园这种.Text类型BlogRSS,因为它们限制请求方的“User-Agent”;

l         采用KxmlParser的自动检测RSS XML文档的编码格式,所以不用用户专门设置编码格式。

2 设计思路

摘要:本章描述RSS无线阅读器J2ME版本的设计思路。

2.1. RSS XML读取及解析

关键三个包:

l         javax.microedition.io. HttpConnection;

l         org.kxml2.io. KXmlParser;

l         org.xmlpull.v1.*。

HttpConnection

下面来看看如何用HttpConnection类来请求远端的RSS服务器并获取RSS XML数据。

第一步是使用Connector类打开一个到服务器的连接,我们将把这个连接强制转换为需要的HttpConnection类型。

代码

HttpConnection hc = null;

hc = (HttpConnection) Connector.open( url );

hc.setRequestMethod(HttpConnection.GET);

接下来,我们得到HttpConnection上的一个InputStream,允许我们一个字符一个字符的读取服务器的响应数据。

代码

parseRssFeedXml( hc.openInputStream() );

public void parseRssFeedXml(InputStream is);

org.kxml2.io. KxmlParser

parseRssFeedXml函数就是负责用KXmlParser来解析这响应数据。

kxml2官方站点:http://kxml.sourceforge.net/。

下载kxml2代码:http://sourceforge.net/project/showfiles.php?group_id=9157&package_id=58653。

Enhydra的KXML是一个被设计用于J2ME设备的只占很小存储空间的XML语法分析程序,虽然它也可以被用于其它需要小型XML语法分析程序的环境,比如Applet。KXML支持以下特性:

1、支持XML名称空间;

2、用"松散"模式分析HTML或其它SGML格式;

3、占用很少的存储空间(21 kbps;

4、基于Pull的分析;

5、支持XML写操作;

6、可选的DOM支持;

7、可选的WAP支持。

KXML支持DOM语法分析和操作,但是不支持push语法分析。取而代之,它使用一种稍微不同的称为“Pull”的分析方法。与push语法分析相反,Pull语法分析让程序员从语法分析程序中“拉”出下一个事件。

Xmlpull官方站点:http://www.xmlpull.org/

优点:不必等整个文档解析完成,部分求值结果早就可以开始反馈给用户。

下面我们看看KXML如何做一个Pull语法分析程序。

首先我们需要创建了一个XmlParser,并把它传到一个InputStream中。

代码

public void parseRssFeedXml(InputStream is)

throws IOException, XmlPullParserException {

KXmlParser  parser = new KXmlParser();

parser.setInput( is, null); // 设置null让KXmlParser自动检测该使用哪种编码

其次,我们需要跳过RSS根节点的“rss”之类的东西。

代码

parser.nextTag();

parser.require(parser.START_TAG, null, null);

下面,我们来寻找RSS中的第一个“item”节点,它代表这个RSS文档中确实包含了新闻条目。这是通过下面的循环做到的。parser.next()的含义是“Get next parsing event”,这样就可以遍历文档,如果找不到item节点,就抛出一个异常。

代码

while(!"item".equals(parser.getName()) ){

/** Check if document doesn't include any item tags */

if( parser.next() == parser.END_DOCUMENT )

throw new IOException("No items in RSS feed!");

}

确认有item节点后,我们来寻找RSS中代表每一个新闻的“item”节点下的三个节点“title”“link”“description”,这是通过下面的循环做到的。parser.next()的含义是“Call next() event if it is START_TAG or END_TAG otherwise throw an exception”,这样就可以遍历文档找全所有的新闻的主题、链接和摘要了。

代码

/** Parse <item> tags */

do {

parser.require(parser.START_TAG, null, null);

/** Initialize properties */

title = "";

description = "";

link = "";

/** One <item> tag handling*/

while (parser.nextTag() != parser.END_TAG) {

parser.require(parser.START_TAG, null, null);

String name = parser.getName();

String text = parser.nextText();

/** Save item property values */

if (name.equals("title"))

title = text;

else if (name.equals("description"))

description = text;

else if (name.equals("link"))

link = text;

parser.require(parser.END_TAG, null, name);

}

/** Create new RSS item and add it do RSS document's item

*  collection

*/

RssItem rssItem = new RssItem(title, link, description);

m_rssFeed.getItems().addElement( rssItem );

parser.nextTag();

} while("item".equals(parser.getName()));

2.2. MVC设计模式

划分为四个模块:

l         midlet:

n         RssReaderMIDlet.java:

u       这当然是MIDlet必须的入口;它负责初始化控制器GUIController

l         Model,模型:

n         RssFeed.java

u       Rss Feed所对应的类实体,基本上有这么几个属性:

l         在RMS中存储的id序号;

l         Feed名称,如“博客堂”或“博客园”;

l         Feed的URL,如http://blog.csdn.net/zhengyun_ustc/Rss.aspx;

n         RssFeedParser.java

u       获取RSS XML并解析的类

n         RssItem.java

u       对应于RSS Feed返回的每一个新闻条目的类实体,包含主题、摘要以及链接;

l         View,视图:

n         About.java

u       “关于我”的Alert界面

n         RssFeedAdd.java

u       “添加Rss Feed书签”的Form界面

n         RssFeedEdit.java

u       “编辑Rss Feed书签”的Form界面

n         RssFeedList.java

u       “Rss Feed列表”的Form界面

n         RssFeedOpen.java

u       “读取Rss Feed新闻”的Form界面

n         RssFeedView.java

u       “查看Rss Feed书签”的Form界面

n         RssItemView.java

u       “查看新闻摘要”的Form界面

n         WaitFlash.java

u       “动画等待画面”的Canvas界面

l         controller

n         GUIController.java

u       MVC中的控制器部分,负责界面事件的处理,以及决定该显示哪一个Form

控制器的事件处理部分:

下面来看看如何处理界面事件。

代码

public void handleEvent( int eventID,Object[] args){

switch (eventID)

{

case EventID.EVENT_EXIT:

{

System.gc();     // 通知进行垃圾收集

Thread.yield();  // 本线程暂停一下,使得GC可以马上获得机会运行

rssMidlet.exit(false);

break;

}

case EventID.EVENT_VIEW_DETAIL:

{

setCurrent(openForm);

openForm.setRss((RssFeed)args[0]);

break;

}

……

每一个Form的如何转发事件:

每一个Form上也有事件响应,并可以自行处理事件,然后加入参数,进一步转发事件到控制器上。这个概念来自于garrey的手机电话本源代码。

代码

/*

* 内部监听器,监听器监听所有Command事件,并把事件响应推出来让控制器处理

*/

private class RssFeedAddListener implements CommandListener{

public void commandAction(Command command, Displayable disp){

if(command == BACK_COMMAND){

controller.handleEvent(GUIController.EventID.EVENT_NEW_BACK, null);

}

else if(command == SAVE_COMMAND){

String title      =     titleField.getString();

String url              =     urlField.getString();

if((title == null || title.equals(""))

|| (url == null || url.equals("") || url.equals("http://"))){

return;

}

Object[] args = {title, url};

controller.handleEvent(GUIController.EventID.EVENT_NEW_SAVE, args);

}//end else

}

}//end inner class

2.3. 读取新闻的后台线程问题

我们在RssFeedOpen这个“读取Rss Feed新闻”的Form界面中,做了一点特殊处理,这样才能够后台线程专门读取RSS XML,而前台界面只需要负责跟进显示解析出来的RSS新闻条目即可了。

所以我们的类这么声明:

代码

public class RssFeedOpen extends Form

implements Runnable

我们为了实现,特地实现了一个run函数,它不断地循环查看标志m_getPage,如果是true,则说明后台线程应该去获取RSS XML了。否则,就睡眠一段时间。

代码

public void run(){

/* Use networking if necessary */

long lngStart;

long lngTimeTaken;

while(true) {

try {

//  我们是依靠m_getPage来判断是否去得到并解析Rss XML的.

//  如果当前m_getPage是false,那么本线程就只能先睡眠一段时间了.

if( m_getPage ) {

try {

        /** Get RSS feed */

              m_curRssParser.parseRssFeed();

              setCurrentDispalyToHeaderList();

}catch(Exception e) {

}

m_getPage = false;

}

lngStart = System.currentTimeMillis();

lngTimeTaken = System.currentTimeMillis() - lngStart;

if(lngTimeTaken < 100)

m_netThread.sleep(75 - lngTimeTaken);

} catch (InterruptedException e) {

break;

}

}

}

3 设计过程中需要特别指出的问题

摘要:本章给出了 RSS无线阅读器J2ME版本的设计过程中需要特别指出的问题。

3.2. HttpConnection请求博客堂/博客园问题

在请求Rss Feed时,遇到一个奇怪的问题。别的RSS源都没有问题,唯独博客堂/博客园始终返回这样的错误信息:

Bad Request (Invalid Header Name)

看来是HttpConnection请求时的Header设置问题。

最终经过反复试验,发现不能设置“User-Agent”字段,否则对方.Text应用不接受。

所以我把下面的代码注释:

hc.setRequestProperty("User-Agent",

"Profile/MIDP-1.0 Configuration/CLDC-1.0");

3.3. 自动识别RSS XML编码问题

Tommi的代码中,是直接用:

parser.setInput( is,"utf-8"); // 设置读取用UTF-8编码

来解析XML的。这样会有问题。

后来看到KXML2的KXMLParser.java中setInput函数其实是可以自动处理编码问题的:

代码

public void setInput(InputStream is, String _enc){

….

if (enc == null) {

// read four bytes

int chk = 0;

while (srcCount < 4) {

int i = is.read();

if (i == -1)

break;

chk = (chk << 8) | i;

srcBuf[srcCount++] = (char) i;

}

if (srcCount == 4) {

switch (chk) {

case 0x00000FEFF :

enc = "UTF-32BE";

srcCount = 0;

break;

case 0x0FFFE0000 :

enc = "UTF-32LE";

srcCount = 0;

break;

case 0x03c :

enc = "UTF-32BE";

srcBuf[0] = '<';

srcCount = 1;

break;

case 0x03c000000 :

enc = "UTF-32LE";

srcBuf[0] = '<';

srcCount = 1;

break;

case 0x0003c003f :

enc = "UTF-16BE";

srcBuf[0] = '<';

srcBuf[1] = '?';

srcCount = 2;

break;

case 0x03c003f00 :

enc = "UTF-16LE";

srcBuf[0] = '<';

srcBuf[1] = '?';

srcCount = 2;

break;

4 资源

我的RssReader资源:

1:《[J2ME]RSSOwlMidlet(RSS无线阅读器)开源说明》

2:《[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明》

3:下载源代码:http://files.cnblogs.com/zhengyun_ustc/RSSOwlMidlet-src.rar

4:下载midlet:jad: RSSOwlMidlet.jad jar: RSSOwlMidlet.jar (jar包可能有点偏大,您可以进行混淆来缩小)

 

网络资源:

1:How to create a J2ME MIDP RSS Reader application with NetBeans 4.0 作者 Tommi Laukkanen

2:J2ME手机电话本 作者 garrey

3:探索J2ME:对记录进行排序

4:kxml2官方站点:http://kxml.sourceforge.net/

5:Xmlpull官方站点:http://www.xmlpull.org/

6:实例教您KXML:J2ME中XML语法分析的利器

编写者

日期

关键词

郑昀@ultrapower

2005-10-07

RssReader RssFeed Channel

j2me midp midlet

kxml xmlpull

RMS

RssOwl

java

[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明相关推荐

  1. QT实现RSS新闻阅读器

    QT实现RSS新闻阅读器 项目简介 项目技术 项目展示 主要源码片段解析 获取完整项目源码传送门 项目简介 一个QML RSS新闻阅读器,它使用XmlListModel和XmlRole下载XML数据, ...

  2. J2ME平台下文本阅读器的实现

    J2ME平台下文本阅读器的实现 J2ME平台下文本阅读器的实现 摘要:本文利用J2ME技术开发了一个文本阅读器,实现了手机对文本文件的显示,给出了该程序的实现代码,并对其关键技术进行了详细阐述. 关键 ...

  3. News Explorer for Mac(RSS新闻阅读器)

    News Explorer mac 破解版是一款专为新闻爱好者所设计的RSS新闻阅读器.News Explorer for Mac支持在所有的Apple设备同步你的文件夹设置,RSS新闻订阅,收藏夹和 ...

  4. RSS新闻阅读器的设计与实现

    摘 要:以RSS技术作为基础技术支持,设计了一个可以帮助人们方便阅读新闻的RSS阅读系统.该系统是由MySQL数据库的建构,结合各站点提供的RSS订阅链接,以及SAX算法解析XML文件.借助JavaS ...

  5. RSS制作阅读器(利用RssToolkit for asp.net 2.0)

    (1)在网站根目录下,添加一个Web窗体"ComplexRSS". (2)切换到设计视图,将一个"GridView"控件拖曳到界面中,并设计其样式,具体样式如代 ...

  6. php开源 rss订阅_5个开源RSS feed阅读器

    php开源 rss订阅 四年前停止使用Google阅读器时,许多"技术专家"都称其为RSS提要的终结. 的确,对于某些人来说,社交媒体和其他聚合工具正在满足需要,供读者一旦使用RS ...

  7. Reabble – 出色的 Kindle RSS 在线阅读器

    简介:Reabble 是一款专门为 Kindle 浏览器优化的 RSS 阅读器,基于在线阅读器 Inoreader 服务,可以让你在Kindle 上每日阅读新鲜内容. 买kindle有一段时间了,经常 ...

  8. 程序员的RSS手机阅读器,升级

    修改分类中添加多条的显示的问题 下载地址:http://download.csdn.net/detail/itshu/4317683

  9. android rss_Android RSS阅读器应用程序

    android rss In this tutorial, we'll be discussing Android RSS Reader and develop an RSS Feed Reader ...

最新文章

  1. centos7离线安装boost
  2. python消息队列celery_消息队列(kafka/nsq等)与任务队列(celery/ytask等)到底有什么不同?...
  3. 多节锂电串联保护板ic_BMS电池管理系统与锂电池保护板的区别
  4. 常见的网上邻居访问问题
  5. Win11新版右键菜单用不惯?一键切换回Win10经典版!
  6. 【转】异步编程:.NET 4.5 基于任务的异步编程模型(TAP)
  7. Sphinx API文档例子
  8. 【报告分享】迈向万亿市场的直播电商-毕马威+阿里研究院.pdf(附下载链接)...
  9. Web接收实时视频流并显示(flask创建路由接收)| 解决延时不同步问题
  10. 在 Linux 下搭建 Git 服务器
  11. 1 linux下tcp并发服务器的几种设计的模式套路,Linux下几种并发服务器的实现模式(详解)...
  12. 【整理】超细节的BERT/Transformer知识点
  13. 使用Water-Scrum-Fall交付软件
  14. ab测试post如何用文件提交json格式的参数
  15. 10部金融人必看电影!拯救春节剧荒的你
  16. 作文 我眼中的计算机1000字,我眼中的自己作文范文1000字(精选6篇)
  17. 八孔g调短洞箫_八孔g调洞箫曲谱_八孔G调箫G调简谱
  18. 【无标题语音聊天app源码——语音聊天派对】
  19. java 外码 内码_什么是汉字的内码、外码、交换码、字形码?
  20. 焦虑症和植物神经紊乱是同一种疾病吗

热门文章

  1. linux 搜索命令 历史,Linux 控制台神器:搜索历史命令 Ctrl + R ( ctrl + r to search the history command )...
  2. android加一减一控件,Android的步进器(增加/减少值)控件?
  3. 计算机语法分析,电子科技大学-计算机学院-编译原理实验-语法分析.pdf
  4. mysql 常用数据库连接池_常见的数据库连接池
  5. linux 进程调度源码分析,Linux调度器源码分析
  6. linux启动过程中内核拷贝,轻松识破linux内核启动过程中的“”套路“”
  7. python对浏览器的常用操作_Selenium元素的常用操作方法分析
  8. java数据库edit_Java数据库连接——JDBC基础知识(操作数据库:增删改查)
  9. 目前市场上的电脑一体机从计算机种类,电脑一体机发展方向是什么?
  10. python执行过程打印,如何在pytest运行过程中看到正常的打印输出?