【问题标题】:How to wrap these classes into a AsyncClass and then using them?如何将这些类包装成 AsyncClass 然后使用它们?
【发布时间】:2012-03-02 12:13:13
【问题描述】:

我正在尝试组装一个简单的 RSS 阅读器,并在 http://www.ibm.com/developerworks/opensource/library/x-android/ 上找到代码

这样做,我注意到自 Honeycomb 以来您无法从主线程执行网络操作,并且很难将此类包装到工作的 AsyncTask 中:

package tlib.net.rss;

import java.util.ArrayList;
import java.util.List;

import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.util.Xml;

public class SaxFeedParser extends BaseFeedParser {

    public SaxFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        final Message currentMessage = new Message();
        RootElement root = new RootElement("rss");
        final List<Message> messages = new ArrayList<Message>();
        Element channel = root.getChild("channel");
        Element item = channel.getChild(ITEM);
        item.setEndElementListener(new EndElementListener(){
            public void end() {
                messages.add(currentMessage.copy());
            }
        });
        item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setTitle(body);
            }
        });
        item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setLink(body);
            }
        });
        item.getChild(DESCRIPTION).setEndTextElementListener(new 
EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDescription(body);
            }
        });
        item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDate(body);
            }
        });
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

这段代码还调用了基类:BaseFeedParser,我猜它也必须被包装到 AsyncTask 中。 BaseFeedParser 的代码如下所示:

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public abstract class BaseFeedParser implements FeedParser {

    // names of the XML tags
    static final String CHANNEL = "channel";
    static final String PUB_DATE = "pubDate";
    static final  String DESCRIPTION = "description";
    static final  String LINK = "link";
    static final  String TITLE = "title";
    static final  String ITEM = "item";

    private final URL feedUrl;

    protected BaseFeedParser(String feedUrl){
        try {
            this.feedUrl = new URL(feedUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

    protected InputStream getInputStream() {
        try {
            return feedUrl.openConnection().getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

我不知道我是只是愚蠢还是今天过得不好,但我不明白这是怎么发生的。有人可以帮助我和我下午的大脑来完成这项工作吗?

目前我使用:

SaxFeedParser rss = new SaxFeedParser("http://www.androidster.com/android_news.rss");
messages = rss.parse();
for(Message message : messages)
{
   tv.appendText(message);
}

要处理流,如果一切都用 AsyncTask 完成,我会怎么做?

亲切的问候

海姆

【问题讨论】:

    标签: java android rss sax android-strictmode


    【解决方案1】:

    我还没有尝试过,但它应该可以工作。
    基本上,AsyncTask 将检索 url(s) 内容,对其进行解析并发布解析的消息。
    onProgressUpdate() 用于根据需要安全地更新用户界面。

    class ParserTask extends AsyncTask<String, List<Message>, Long> {
    
        protected Long doInBackground(String... urls) {
            if (urls == null || urls.length == 0)
                return null;
            for (String url : urls) {
                SaxFeedParser rss = new SaxFeedParser(url);
                List<Message> messages = rss.parse();
                publishProgress(messages);
            }
            return null; //return somethingForPostExecute;
        }
    
        protected void onProgressUpdate(List<Message>... messages) {
            if (messages == null || messages.length == 0)
                return;
            for (Message message : messages[0]) {
                // tv.appendText(message);
                // or call method from GUI thread (the activity)
            }
        }
    
        protected void onPostExecute(Long nr) {
    
        }
    }
    

    然后你使用类似的东西:

    new ParserTask().execute("http://www.androidster.com/android_news.rss");
    

    或者你可以使用多个网址:

    new ParserTask().execute(new String[]{"http://www.androidster.com/android_news.rss", "..."});
    

    【讨论】:

    • 对我来说很好。您应该尝试另一个 URL,该 URL 似乎已损坏。
    • 我设法将所有内容都放入了一个较小的类中,并在您的帮助下设法让它工作。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2019-11-07
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多