读rss feed - android

时间:2014-09-02 02:58:18

标签: android xml parsing rss

我正在尝试开发一个简单的应用程序,该应用程序从某个URL读取RSS源,然后在列表视图中显示结果。

这是我的RSS阅读器,这是应用程序中的主要内容:

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

public class RssReader {
private String title = null;
private String link = null;
private String description = null;
private ArrayList<RssItem> posts = new ArrayList<RssItem>();
private Thread thread;

private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public volatile boolean parsingComplete = true;

public RssReader(String url) {
    this.urlString = url;
}
public boolean getParsingComplete() {
    return this.parsingComplete;
}
public ArrayList<RssItem> getPosts() {
    return posts;

}
public void parseXML(XmlPullParser parser) {
    int event;
    try {
        event = parser.getEventType();
        while (event != XmlPullParser.END_DOCUMENT) {
            String name = parser.getName();
            switch (event) {
            case XmlPullParser.START_TAG:
                break;
            case XmlPullParser.END_TAG:
                if (name.equals("title")) {
                    title = parser.getText();
                } else if (name.equals("link")) {
                    link = parser.getText();
                } else if (name.equals("description")) {
                    description = parser.getText();
                }
                break;
            }
            if(title != null && link != null && description != null) {
                RssItem item = new RssItem(this.title,this.description,this.link);
                posts.add(item);
                this.title = this.description = this.link = null;
            }
            event = parser.next();
        }
        parsingComplete = false;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void fetchXML() {
    thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL(urlString);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                conn.setReadTimeout(10000 /* milliseconds */);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("GET");
                conn.setDoInput(true);
                // Starts the query
                conn.connect();
                InputStream stream = conn.getInputStream();
                xmlFactoryObject = XmlPullParserFactory.newInstance();
                XmlPullParser myparser = xmlFactoryObject.newPullParser();
                myparser.setFeature(
                        XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
                myparser.setInput(stream, null);
                parseXML(myparser);
                stream.close();
            } catch (Exception e) {
            } finally {
                parsingComplete = true;
            }
        }
    });
    thread.start();
}

这是我的MainActivity:

package com.example.ynetrssproject;

import java.util.ArrayList;

import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.ListView;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

private ListView news;
private String rssUrl = "http://www.themarker.com/cmlink/1.144";
private ArrayList<RssItem> list;
private RssItemAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    news = (ListView) findViewById(R.id.news);
    RssReader reader = new RssReader(rssUrl);
    reader.fetchXML();
    while(true) {
        Log.d("Runnning", "Run");
        if(reader.getParsingComplete()) {
            list = reader.getPosts();
            break;
        }
    }
    adapter = new RssItemAdapter(this, R.layout.post_item_list, list);
    news.setAdapter(adapter);
    }
}

问题在于,每当我调用fetchXML时,最终它会返回一个空的ArrayList。因此,我的列表视图一直是空的。

我的适配器并不是什么大问题。它工作正常。问题是我不断从对象RssReader获取一个空数组列表。我知道这是因为我在代码末尾执行了一个小if语句来检查ArrayList是否为空。

P.S我尝试过多个RSS网址,但没有一个可以使用。 另外,我在清单中添加了Internet的许可。

1 个答案:

答案 0 :(得分:0)

使用SAXParser

public class RssReader {

private String rssUrl;

public RssReader(String rssUrl) {
    this.rssUrl = rssUrl;
}

public List<RssItem> getItems() throws Exception {

    SAXParserFactory factory = SAXParserFactory.newInstance();

    SAXParser saxParser = factory.newSAXParser();

    RssParseHandler handler = new RssParseHandler();

    saxParser.parse(rssUrl, handler);

    return handler.getItems();

}

}

public class RssParseHandler extends DefaultHandler {

private List<RssItem> rssItems;

private RssItem currentItem;

private boolean parsingTitle;

private boolean parsingLink;

public RssParseHandler() {
    rssItems = new ArrayList<RssItem>();
}

public List<RssItem> getItems() {
    return rssItems;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if ("item".equals(qName)) {
        currentItem = new RssItem();
    } else if ("title".equals(qName)) {
        parsingTitle = true;
    } else if ("link".equals(qName)) {
        parsingLink = true;
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if ("item".equals(qName)) {
        rssItems.add(currentItem);
        currentItem = null;
    }else if ("title".equals(qName)) {
        parsingTitle = false;
    }else if ("link".equals(qName)) {
        parsingLink = false;
    }
}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    if (parsingTitle) {
        if (currentItem != null)
            currentItem.setTitle(new String(ch, start, length));
    }else if (parsingLink) {
        if (currentItem != null) {
            currentItem.setLink(new String(ch, start, length));
            parsingLink = false;
        }
    }
}

}

公共类RssItem {

// item title
private String title;
// item link
private String link;

private String id;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getLink() {
    return link;
}

public void setLink(String link) {
    this.link = link;
}


@Override
public String toString() {
    return title;
}

}