天天看點

網易新聞RSS閱讀器

首先需要分析網易RSS訂閱中心的網頁布局情況。

網易RSS訂閱中心:http://www.163.com/rss/

你會發現RSS檔案由一個<channel>元素及其子元素組成,除了頻道本身内容之外,<channel>還以項的形式包含表示頻道中繼資料的元素。

其中頻道下面主要的三個元素就是:

1.title:頻道或提要的名稱。

2.link:與該頻道關聯的WEB站點或者站點區域的URL。

3.description:簡要介紹該頻道是做什麼的。

當然還有其他子元素是可選的,比如常用的有<image>,<language>,<copyright><pubDate>等.

下面我們編寫的RSS閱讀器是包含了四個元素,有titile,link,description,pubDate.

首先:我們建立新聞的實體類:

package com.example.rssview;

public class News {

private String title;//新聞标題

private String link;//新聞網址

private String description;//新聞描述

private String pubDate;//新聞釋出時間

public News() {

}

public News(String title, String link, String description, String pubDate) {

this.title = title;

this.link = link;

this.description = description;

this.pubDate = pubDate;

}

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;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public String getPubDate() {

return pubDate;

}

public void setPubDate(String pubDate) {

this.pubDate = pubDate;

}

}

上面是程式開發的第一步,完成實體類的建立

第二步:我們應該也可想而知,必須解析XML的有用資料,常用的解析XML的方法有三種:DOM解析,SAX解析,PULL解析

因為DOM解析必須讀取所有的XML内容到記憶體裡面,挺耗系統資源的是以,我推薦選擇SAX解析,或者PULL解析。

這裡我選擇SAX解析方法具體代碼如下:

package com.example.rssview;

import java.util.ArrayList;

import java.util.List;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class SAXParserHelper extends DefaultHandler {

private List<News> newsList;//儲存解析的所有新聞資料

private News news;//單個新聞内容

private String nodeName;//判斷是那個元素用

//擷取所有新聞資料

public List<News> getNewsList() {

return newsList;

}

//開始解析XML文檔

@Override

public void startDocument() throws SAXException {

newsList = new ArrayList<News>();

}

//結束解析XML文檔

@Override

public void endDocument() throws SAXException {

// TODO Auto-generated method stub

super.endDocument();

}

//開始解析某個元素

@Override

public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException {

if (localName.equals("title")) {

news = new News();

}

this.nodeName = localName;

}

//結束解析某個元素

@Override

public void endElement(String uri, String localName, String qName)

throws SAXException {

if (localName.equals("item")) {

newsList.add(news);

// Log.i("SAXParserHelper", news.getTitle());

// Log.i("SAXParserHelper", news.getLink());

// Log.i("SAXParserHelper", news.getPubDate());

// Log.i("SAXParserHelper", news.getDescription());

}

}

//解析元素的文本内容

@Override

public void characters(char[] ch, int start, int length)

throws SAXException {

if ("title".equals(this.nodeName)) {

news.setTitle(String.valueOf(ch, start, length));

} else if ("link".equals(this.nodeName)) {

news.setLink(String.valueOf(ch, start, length));

} else if ("description".equals(this.nodeName)) {

news.setDescription(String.valueOf(ch, start, length));

} else if ("pubDate".equals(this.nodeName)) {

news.setPubDate(String.valueOf(ch, start, length));

}

}

}

代碼就不用多解釋了,相信備注已經些的非常的詳細了,也提供了供外部擷取解析資料的方法getNewsList();

第三步:當然是去Activity活動裡面去編寫主要的代碼了

開始我們必須準備包含了listView控件的布局檔案,然後在activity裡面設定布局檔案

當然你也可以直接繼承ListActivity類,這樣更友善程式設計

你也應該知道這是從網絡讀取網址擷取XML資料,根據Android的程式設計原則,耗時的網絡操作不應該在主線程中直接執行,因為這樣會造成主線程的崩潰。

然而android給我們提供了一個異步處理的機制類AsyncTask隻要自己寫個類實作該類把耗時的任務放在doInBackground方法裡面處理就可以了。

當我們獲得網絡資料後就會操作更新UI來顯示解析的XML資料,這個時候就可以在AsyncTask的onPostExecute裡面解決.

也許我們還應該分析一下AsyncTask的三個參數,第一個參數是傳遞進來的參數,比如我們下面會傳入一個網址供AsyncTask解析獲得XML資料,第二個參數就是進度顯示機關我們常常設定為Integer,第三個參數就是doInBackground方法傳回的資料供onPostExecute調用的資料,也就是onPostExecute的參數.

下面我們首先必須獲得網絡的XML。

URL url = null;//建立URL對象

String XmlSourceStr = null;//解析後的XML資料

try {

url = new URL(params[0]);//擷取傳遞進來的網址資源

if (url != null) {

HttpURLConnection conn = (HttpURLConnection) url

.openConnection();//打開連結

InputStreamReader isReader = new InputStreamReader(

conn.getInputStream(), "UTF-8");//讀取資料到InputStreamReader對象中,并設定編碼格式為UTF-8

BufferedReader br = new BufferedReader(isReader);//執行個體化bufferedReader

StringBuilder sb = new StringBuilder();

String line = null;

while ((line = br.readLine()) != null) {

sb.append(line);//讀取XML資料到StringBuilder中

}

isReader.close();//關閉資料流

conn.disconnect();//關閉連接配接

XmlSourceStr = sb.toString();//讀取StringBuilder資料到字元串中

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return XmlSourceStr;//傳回解析的XML字元串資料

這個方法屬于網絡處理比較耗時,相信大家也就知道,應該寫在doInBackground中

擷取網絡的XML資料後,下面就是解析XML的資料,上面已經提到過。我們使用的解析方式是SAX解析。代碼如下:

SAXParserFactory factory = SAXParserFactory.newInstance();//建立SAXParserFactory執行個體

if (result != null) {

try {

SAXParser parser = factory.newSAXParser();//建立SAXParser解析類

XMLReader xmlReader = parser.getXMLReader();//建立XMLReader讀取類

SAXParserHelper helper = new SAXParserHelper();//執行個體化SAX解析方法

xmlReader.setContentHandler(helper);//設定處理器

xmlReader.parse(new InputSource(new StringReader(result)));//讀取需要處理的資料

newsList = helper.getNewsList();//獲得處理的結果

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

上面的操作不屬于網絡因為燈會需要操作更新UI,是以代碼寫在onPostExecute中

下面我們用疊代器周遊處理的結果,當然需要判斷擷取了需要的結果沒有,代碼如下:

if (!newsList.isEmpty()) 

Iterator<News> it = newsList.iterator();

然後建立一個用于接受周遊結果的Map類 Map<String,Object> map=new HashMap<String,Object>();

而simpleAdapter的構造方法中接收的是一個List對象,而上面擷取的每個map,也就隻是單獨的一個新聞,是以必須建立List<Map<String,Object>> newsList=new ArrayList<Map<String,Object>>();将每一條map新聞儲存在newsList當中.

對于剛才說的simpleAdapter一般有一點android基礎的應該都不陌生,沒錯他就是簡單的擴充卡.等會将資料顯示到listView上面可少不了他。

現在我們就來設定listView顯示新聞,代碼如下:

首先綁定listView界面

SimpleAdapter adapter=new SimpleAdapter(Context,list對象,布局檔案,listView中資料項,listView中資料項對應的ID);

第一個參數并不陌生就是上下文了,簡單說就是繼承活動的類名.this。

第二個參數屬于剛才擷取所有新聞的newsList.

第三個參數就是listView要顯示的布局檔案樣式R.layout.你的布局檔案名.

第四個參數就是map.put方法中前面字元串的名稱.

第五個參數就是第三個參數布局檔案中用于顯示新聞每個項的ID;

最後設定到listView中就可以了,具體代碼如下:

if (!newsList.isEmpty()) {

Iterator<News> it = newsList.iterator();

while (it.hasNext()) {

News news = (News) it.next();

HashMap<String, Object> map = new HashMap<String, Object>();

map.put("title", news.getTitle());

map.put("pubDate", news.getPubDate());

Log.i("MainActivity", news.getTitle());

Log.i("MainActivity", news.getPubDate());

mData.add(map);

}

SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,

mData, R.layout.list_item, new String[] { "title",

"pubDate" }, new int[] { R.id.title,

R.id.pubDate });

newsListView.setAdapter(adapter);

}

當然這裡我并沒有做顯示新聞詳細的内容顯示功能,不過相信看懂上面的代碼後,你們也知道設定顯示新聞相信内容和擷取上面的代碼有異曲同工之妙了。

好了,簡單的RSS閱讀器就講到這樣。我的第一篇博文,雖然不盡完美,但也算是講解程式的一個起點。

轉載于:https://www.cnblogs.com/liyuanjinglyj/p/rss.html