日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鄭昀@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年就已經通行天下了,最通常的是BlogRSS輸出,當然許多其他類型的站點也都提供了本站內容的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:對記錄進行排序》的代碼,放棄了garreyRecordComparator比較器的實現。

另外,在調試過程中,也加入了我的一些思考,以及兼容各種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

EnhydraKXML是一個被設計用于J2ME設備的只占很小存儲空間的XML語法分析程序,雖然它也可以被用于其它需要小型XML語法分析程序的環境,比如AppletKXML支持以下特性:

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); //?設置nullKXmlParser自動檢測該使用哪種編碼

?

其次,我們需要跳過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?????????FeedURL,如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_getPagefalse,那么本線程就只能先睡眠一段時間了.

????????????????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的。這樣會有問題。

?

后來看到KXML2KXMLParser.javasetInput函數其實是可以自動處理編碼問題的:

代碼

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包可能有點偏大,您可以進行混淆來縮小)

?

網絡資源:

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

2J2ME手機電話本?作者?garrey

3探索J2ME:對記錄進行排序

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

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

6:實例教您KXMLJ2MEXML語法分析的利器

?

?

編寫者

日期

關鍵詞

鄭昀@ultrapower

2005-10-07

RssReader RssFeed Channel

j2me midp midlet

kxml xmlpull

RMS

RssOwl

java

?

總結

以上是生活随笔為你收集整理的[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。