旁观者

参与软件开发开发这些年来,不断地遇到新领域新知识点,屡屡感受到新进入者的迷惑和彷徨,所以对遇到的每一个问题都详细记录问题现象、解决思路以及解决方案,并在blog中留下印迹,以备他日有心人google之而知之。
你们的新手之痛,你们的新业务发展之初的思路混沌,我都感同身受,所以欢迎和我一起探讨这些话题,诸如,文本挖掘/自然语言处理/Web3.0/J2ME/Web2.0/IVR/SMS/MMS/WAP/SIP/等等,知无不言言无不尽。
posts - 445, comments - 798, trackbacks - 39, articles - 0
   ::  ::  ::  :: 订阅 订阅 :: 管理

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

Posted on 2005-10-07 23:20 旁观者 阅读(7307) 评论(14)  编辑 收藏 网摘 所属分类: Java
 

郑昀@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:下载midletjad: 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:下载midletjad: 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

 

Feedback

#1楼[楼主]   回复  引用  查看    

2005-10-21 14:37 by 让变化成为计划的一部分      
有一位网友来信说“下载了您写的程式,在可以正常编译通过,并且在WTK2.2模拟器下可以上网浏览
RSS列表。
但是其他模拟器都不能做到上网浏览RSS列表。
用NOKIA60模拟器最后会报一个错误
Error: Error while parsing RSS data: w: unresolved: (position:TEXT
@14:224 in java.io.InputStreamReader@ea0ef881
我在多台机器上做了测试,比如索爱K700,NOKIA6600
都不能浏览RSS列表
您碰到这个问题了吗?
”。

我在Nokia7610上也遇到过类似情况,原因在于

如果你看到"Error: Error while parsing RSS data: w: unresolved: (position:TEXT
@14:224 in java.io.InputStreamReader@ea0ef881"的错误,那么是不是前面还输出了许多XML的节点名称,那么是否有"#==XML
Node Name:html"这样的输出呢?
如果有,这表明该Rss Feed返回的并不是xml,而是html文档。
如下所示:

??require START_TAG
#==XML Node Name:html
#==XML Node Name:null
#==XML Node Name:head
#==XML Node Name:null
#==XML Node Name:title
#==XML Node Name:null
#==XML Node Name:title
#==XML Node Name:null
#==XML Node Name:meta
#==XML Node Name:meta
#==XML Node Name:null
#==XML Node Name:link
#==XML Node Name:link
#==XML Node Name:null
#==XML Node Name:link
#==XML Node Name:link
#==XML Node Name:null
#==XML Node Name:head
#==XML Node Name:null
#==XML Node Name:body
#==XML Node Name:null
#==XML Node Name:form
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:img
#==XML Node Name:img
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:div
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
#==XML Node Name:null
#==XML Node Name:a
Error: Error while parsing RSS data:
org.xmlpull.v1.XmlPullParserException: unresolved: &nbsp;
(position:TEXT @14:224 in java.io.InputStreamReader@f828ed68)


我修改了代码,使得解析XML时的错误能够以Alert形式告诉用户。

基本上在Nokia7610真机上试验通过了。

并更新了代码和jar:

http://www.cnblogs.com/Files/zhengyun_ustc/RSSOwlMidlet-deployed.rar">http://www.cnblogs.com/Files/zhengyun_ustc/RSSOwlMidlet-deployed.rar

http://www.cnblogs.com/Files/zhengyun_ustc/RSSOwlMidlet-src.rar">http://www.cnblogs.com/Files/zhengyun_ustc/RSSOwlMidlet-src.rar

#2楼   回复  引用    

2006-10-10 20:24 by codeant # hotmail[未注册用户]
我以前从来没做过java开发,不过这次因为打算在手机上安装这个阅读器的关系,靠着c++功底花了近一整天的时间建立开发环境eclipse + eclipseMe + wtk_toolkit 2.2(patched)把这个程序改写了几处:
1. appendRSSItem时如果正在查看内容会弹回列表页
2. 列表页装入完成时如果正在查看内容也会弹回
3. 很多RSS源包含了HTML Tags和转义符,用正则表达式给去掉了

修改后的代码可从以下网址下载(版本号以及一切版权信息都没有更动):
http://www.freedom-fire.com/soft/RSSOwlMidlet.rar

#3楼[楼主]   回复  引用  查看    

2006-10-10 22:07 by 让变化成为计划的一部分      
谢谢!
这是我初学j2me的练习。
后来我又用canvas重写了一个,http://blog.csdn.net/zhengyun_ustc/archive/2005/12/27/563341.aspx">http://blog.csdn.net/zhengyun_ustc/archive/2005/12/27/563341.aspx
你可以看看。
这里面把html解析以及其他复杂操作都放在了服务器端,而不是手机上。
之所以这样,原因很简单,用户目前手头上的多数手机无法支撑如此大量内存频繁操作。
rss源动辄几十KB上百KB,这样的数据量操作并不适合手机端作复杂变换。几乎流行的RSS手机阅读器都不会这么做。

#4楼   回复  引用    

2006-10-11 15:15 by codeant # hotmail[未注册用户]
相当同意你的观点,事实上我也认为现阶段你的方案和我所想的颇有共通,当然某些方面我比较偏激点,甚至打算实现过滤阅读过的文章之类的。不过因为精力有限,暂时恐怕是没法搞了,想想而已。

今天花了点时间把tinylinezip添加进了阅读器里。 如果你还有使用的话会发现默认建立的第一个博客项目无法解析,实际上就是因为header里面写了支持gzip但实际并没有gzip支持,kxml2虽然支持wbxml,但那是wap来的,我们都走的http。不知道你用的什么网络连接,我用的可还是可怜巴巴的8元GPRS套餐,虽然每k只要1分钱,架不住经常看啊(偶喜欢上下班路上坐车时看看新闻小说天气什么的),有了gzip支持,一个简单的用XMLHttp读取远程页面并打开动态文件压缩gzip返回就能省好多带宽而且快上不少了。

看了一下新作,没仔细研究,还是那句精力有限。不过看上去似乎依然没有gzip的支持... 这两天看看有没有时间,也许还会给这个程序加上读取中/完毕的状态提示和读取中停止读取的功能项。 过两天再传上来请你指正指正。

倒是另一个观点有些差异的地方探讨探讨,我是指web+java这块,其实我更倾向于使用Opera Mini来访问web gzip处理过的资源,比如rss + xslt转义生成一个简单查看页,对于一个rss可以只列出title,点击进入后才察看全文或者是可以先看到全文最前面的50字,这样的东西做起来简单快捷而且通用,用智能手机的朋友们也可以通过其他浏览器使用这样的服务。 而带宽以及内存在未来都能够得到相当的缓解,实在没有必要在性能上太过较真,当然,这也是我没把这种玩意当成企业级应用。 但我确实觉得应该让东西的可用性更广,而专业性更强。

更多的就不想了,我只是想要一个满足一下自己简单要求的程序就好,何况我对java非常陌生,在此之前的多年开发里也仅只写过个HelloWorld.java而已。这回为了这玩意可是google了不下百回了。

嗯,上次回复忘了个事这回补上: 十分感谢你的程序:)

#5楼   回复  引用    

2006-10-11 15:28 by codeant # hotmail[未注册用户]
发完看了一遍,想起个事,颇汗,gzip支持只是加了以下内容:

import com.tinyline.util.GZIPInputStream;

...

System.out.println("/** openInputStream to:" + url);
if ("gzip".equals(hc.getEncoding()))
bParseOk = parseRssFeedXml( new GZIPInputStream(hc.openInputStream()) );
else
bParseOk = parseRssFeedXml( hc.openInputStream() );

顺便问一个问题,有空的话还望指教一下: 我把tinylinezip.jar放deploy里并且添加到build path,但运行时一直ALERT: java/lang/VerifyError: ......。
现在能用是decompile后手动把命名为保留字的变量和函数名都改掉了,可以说是的毁容版。 不过万一碰上包里文件多的话就死翘了。 换了关键字搜了好多篇文章不过还是没解决。

班门弄斧,见笑,见笑。

#6楼[楼主]   回复  引用  查看    

2006-10-11 18:01 by 让变化成为计划的一部分      
1:
作为手机阅读博客或者新闻或者论坛的阅读器,推介你使用一下下面两家的kjava产品,
从中你就能看出高手们的思路。
而不要一味自己闭门造车。

http://www.ucfly.com/">http://www.ucfly.com/ , ucweb软件

http://www.datuu.com/">http://www.datuu.com/ , 手机大头

2:
作为J2ME权威站点J2MEDEV.COM的超级版主之一,我强力向你推荐
我们的论坛
http://www.j2medev.com/bbs/index.asp">http://www.j2medev.com/bbs/index.asp

你的很多问题在那里都会得到回复,那里也有很多精华帖子。不用四处搜索。

3:
C++和J2ME思路上完全是两码事。C++的经验在j2me上基本没有太大用处。

4:
如果你就RSS阅读器有问题,建议你到我的CSDN Blog上讨论问题,我经常在那里。这里不常来。

#7楼[楼主]   回复  引用  查看    

2006-10-11 18:06 by 让变化成为计划的一部分      
4:
作j2me联网的,基本上都走CMWAP通道。这个基本上各省都是10、20块钱包月50M的流量等等不同的套餐。
你说的是CMNET通道吧。

#8楼   回复  引用    

2006-11-22 00:39 by XFly[未注册用户]
谢谢!~~刚好在找手机端的Rss资料,就找到这了,非常实用!~
不过中间说到
"for循环删除有一个非常奇怪的地方,在我的机器上试验,是隔一个删一个,导致无法删除干净?!所以最后不得不采用下面的while循环始终删除第一个元素的办法!这也许是一个MIDP1.0的bug。"
这个应该不算bug吧,j2se里面list都是这样啊,前面删掉了,后面序号当然都往前移了.

#9楼[楼主]   回复  引用  查看    

2006-11-22 09:45 by 让变化成为计划的一部分      
呵呵,从去年开始几乎每个人上来都说这段话有问题。
如果你们看了代码的话,就会知道代码早就改成这样的了:
/*
* 由于MIDP 2.0中才定义了List的deleteAll()方法,
* 但是MIDP1.0中List支持delete(int itemNum).
* 所以在MIDP1.0中,可以使用List的size()得到当前List中的Item的数量,
* 然后使用for循环delete(int itemNum),这样在MIDP1.0中实现deleteAll的功能。
*/
private synchronized void deleteAll()
{
System.out.println("!-- Enter RssFeedList::deleteAll --!");
for(int i = 0;i < this.size();i++){
this.delete(i);
}
}



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 249941




相关文章:

相关链接: