read rss feed - android

2019-09-21 00:41发布

问题:

I'm trying to develop a simple application that reads rss feeds from a certain URL and then displays the results in a list view.

Here is my rss reader, which is the main thing in the app:

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();
}

And here is my 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);
    }
}

The problem is that everytime I call fetchXML, eventually it returns me an empty ArrayList. Therefore, my listview keeps being empty.

My adapter isn't such a big deal. It works fine. The problem is that I keep getting an empty array list from the object RssReader. I know this because I performed a little if statement at the end of the code just to check if the ArrayList is empty.

P.S I have tried with multiple RSS urls but none of them works. Also, I added the permission of Internet in my manifest.

回答1:

use SAXParser

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;
        }
    }
}
}
public class 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;
}

}