話說︰
小鰻最近在忙一個專案,其中有一段剛好跟RSS有關,研究了3、4天的SDK範例大全和另一本開發實務的書,在這裡稍微把概念記錄下來。
android有提供幾種方式去抓取RSS資料來源,最為人知的就是使用SAXParser分析器了。
RSS說簡單了,也只不過是一個xml檔(也有可能是其他的副檔名)。它有一定的規範與格式,所以在解析各大新聞臺的RSS時,也變得有跡可尋。
以下是常看到的RSSxml檔案格式
<itme>
<title>新聞的標題</title>
<link>新聞的連結網址</link>
<description>新聞內容簡述</description>
<pubDate>發佈新聞的時間</pubDate>
</item>
所以啦,所謂的RSS解析器,說白一點,就是在這些標籤裡,把字取出來啦!
通常各大網站都會提供RSS新聞的連結,像yam新聞的RSS網址是這樣子的︰
http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml
所以,到時候程式裡一定要有個地方能夠存這個網址。
------------------------------------------------------
RSS解析器裡會有4個工人分工合作著
(1)XMLReader - 閱讀工人
(2)MyAdapter(繼承自BaseAdapter) - 版面配置工人
(3)MyHandler(繼承自DefaultHandler) - 文字分配工人
(4)一個具物件導向特性的類別News - 模版工人
要能夠解析一份RSS,Android交給了4個工人幫忙
(1)XMLReader
第1個工人既然叫閱讀工人,我們就來看看這個工人是怎麼讀書的吧︰
path = "http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml";
URL url = null;
try{
url = new URL(path);//呼叫網址進來
SAXParserFactory spf = SAXParserFactory.newInstance();//先蓋一個工廠
SAXParser sp = spf.newSAXParser();//工廠有一個知識不太高的解析工人
XMLReader xr = sp.getXMLReader();//也有一個閱讀工人
MyHandler myHandler = new MyHandler();//用到了我們之後建立的分配工人
xr.setContentHandler(myHandler);//將閱讀工人和分配工人做結合
xr.parse(new InputSource(url.openStream()));//閱讀工人用parse去開啟一個InputStream放資料
data = myHandler.getParsedData();//getParsedData()方法會在myHandler裡看到
}catch(Exception e){
log.i("message","wrong!");
}
原來光一個閱讀工人,就已經做了一些的前置動作了。
(2)MyAdapter
其實這個版面配置工人還真的是可有可無,要不是主編要求取出來的"新聞發佈時間"不能和"新聞標題"一樣大,還真的是不用請版面配置工人出來,用原本的android預設配置就好
這個配置工人,android希望我們繼承自BaseAdapter,而且,還規範了我們必須實作以下4個method
//建構子
public MyAdapter(Context context,List lt){
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount(){
return 數量;
}
@Override
public int getItem(int position){
return position;
}
@Override
public int getItemId(){
return position;
}
@Override
public View getView(int position,View convertView,ViewGroup par){
ViewHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.news_row, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
class ViewHolder{//為自己訂的版面的xml做一個類別
TextView text;
}
}
最後面這段「為自己訂的版面的xml做一個類別」是什麼意思呢?
其實配置工人通常會帶一個小老婆出現︰
news_row.xml
他們其實是很親密的,正所謂孟不離焦啊!
一個負責外表(xml),另一個是對應的骨架(class ViewHolder)
(3)MyHandler
既然叫Handler,當然什麼事都要幫你搞定囉!
它也有幾個一定要我們覆寫的method
public class MyHandler extends DefaultHandler{
private List<News> li;
public List getParsedData(){//這個是我們自己寫的,沒有一定要覆寫
return li;
}
@Override
pubilc void starDocument() throws SAXExcption{
li = new ArrayList<News>();//在程式解析之初,先建立一個ArrayList容器
}
@Override
pubilc void endDocument() throws SAXExcption{
}
@Override
pubilc void starElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
news = new News();//在程式解析之初,先產生實體
}
@Override
pubilc void endElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
//更多程式碼
}
@Override //取標籤內的字的方式
pubilc void characters(char ch[], int start, int length){
//更多程式碼
}
}
這段的程式跑法是︰
starElement()→characters()→endElement()→starElement()→characters()→endElement().....
將一個一個的標籤辨識出來並跑完
(4)News類別
既然叫模版工人,就是說從解析器解出來的字串,要有一個一個的對應去接收資料,好讓容器能歸納整理咩
所以,模版的程式碼超基本
public class News{
private String title=""; //新聞的標題存在這裡
private String link=""; //新聞的連結網址存在這裡
private String desc=""; //新聞的大綱描述存在這裡
private String date=""; //新聞的發佈時間存在這裡
//以下是一堆的getter和setter
//像︰
public String getTitle(){
return title;
}
public String setTitle(String title){
this.title = title;
}
//更多程式碼
}
最後最後,有一個超關鍵,如果你忽略了,可能都不知道為什麼會無法解析或上網咧!
請你在AndroidManifest.xml這個apk基本配面版中的<application>區塊外,做以下的新增
<uses-permission android:name="android.permission.INTERNET" />
因為android預設的apk連網功能是關閉的,必須透過上述的設定將上網權限打開。
好啦!大功告成。
程式不多不少,但是就是因為大家的配合,才產生出了好用的RSS隨手新聞。
下臺一鞠躬(笑)。