Android RSS订阅

1. RSS简介

RSSReally Simple Syndication,简易信息聚合。RSS是一种描述和同步网站内容的格式,用于与其他站点之间共享内容。RSS目前广泛用于晚上新闻。

2. RSS文件格式

RSS由一个channel元素及其子元素组成,包括itemtitlelinkdescription等。
item元素是最重要的部分,可以包含多个,子元素包括titlelinkdescription等。

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/css" href="/css/rsstyle.css" ?>
<rss version="2.0">
    <channel>
        <title>科学网新闻RSS——首页头条</title>
        <link>http://news.sciencenet.cn</link>
        <description>科学网是由科学院、工程院和基金委主管,中国科学报社主办的公益性网站,提供新闻、博客、论坛、免费信息发布、资料互助等服务!</description>
        <item>
            <title>
                <![CDATA[武汉病毒所发现RNA干扰具有抗病毒免疫作用]]>
            </title>
            <link>
                <![CDATA[http://news.sciencenet.cn/htmlnews/2017/6/380116.shtm]]>
            </link>
            <description>
                <![CDATA[6月21日,国际学术期刊《免疫》(Immunity)上刊发论文显示,科学家证明,以往只在真菌、植物和无脊椎动物中确认发挥抗病毒免疫作用的RNA干扰(RNAi),在哺乳动物中也能发挥同样的作用。这项工...]]>
            </description>
            <copyright>甘晓 陈逗逗</copyright>
            <pubDate>2017-06-21 14:39</pubDate>
            <comments>http://news.sciencenet.cn/html/comment.aspx?id=380116</comments>
        </item>
    </channel>
</rss>

3. RSS解析

利用XmlPullParser解析

private List<ChannelItem> parseRss(String content) {
    List<ChannelItem> itemList = new ArrayList<>();
    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(new BufferedReader(new StringReader(content)));

        int eventType = parser.getEventType();
        ChannelItem item = null;
        String text = null;

        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {
                if ("item".equals(parser.getName())) {
                    item = new ChannelItem();
                }
            } else if (eventType == XmlPullParser.END_TAG) {
                if ("item".equals(parser.getName())) {
                    itemList.add(item);
                } else if ("title".equals(parser.getName())) {
                    if (item != null)
                        item.title = text;
                } else if ("link".equals(parser.getName())) {
                    if (item != null)
                        item.link = text;
                } else if ("description".equals(parser.getName())) {
                    if (item != null)
                        item.description = text;
                }
            } else if (eventType == XmlPullParser.TEXT) {
                text = parser.getText();
            }
            eventType = parser.next();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return itemList;
}

private class ChannelItem {
    String title;
    String link;
    String description;
}

利用AsyncTask加载数据

private class RssTask extends AsyncTask<String, Integer, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            URL url = new URL("http://www.sciencenet.cn/xml/news-0.aspx?news=0");

            URLConnection connection = url.openConnection();

            BufferedReader br = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
            String line = null;
            StringBuffer buffer = new StringBuffer();

            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }

            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (s != null) {
            final List<ChannelItem> itemList = parseRss(s);
            List<Map<String, String>> data = new ArrayList<>();

            for (ChannelItem item : itemList) {
                Map<String, String> itemMap = new HashMap<>();
                itemMap.put("title", item.title);
                itemMap.put("desc", item.description);
                data.add(itemMap);
            }

            mListView.setAdapter(new SimpleAdapter(RssActivity.this, data,
                    R.layout.list_item_rss,
                    new String[]{"title", "desc"},
                    new int[]{R.id.tv_title, R.id.tv_description}));
            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent,
                                        View view, int position, long id) {
                    Toast.makeText(RssActivity.this, itemList.get(position).link,
                            Toast.LENGTH_LONG).show();
                }
            });
        }

    }

}

布局文件list_item_rss.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="45dp">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="5dp"
        android:textSize="16sp"
        android:gravity="center_vertical"/>

    <TextView
        android:id="@+id/tv_description"
        android:layout_width="match_parent"
        android:layout_height="15dp"
        android:layout_marginLeft="15dp"
        android:textSize="12sp"
        android:gravity="center_vertical"/>

</LinearLayout>

4. 效果如下

在这里插入图片描述