國內外的電台數據很多,起碼有好幾百,所以把這些數據都寫到代碼里面是不實際的。只能寫成一個數據文件,程序啟動的時候再去加載。保存這些簡單數據,我們肯定會優先使用XML文件,今天講講如何讀取XML里面的數據,然后填充到列表里面。
再把這張老截圖貼出來,方便后面對應查看XML的數據。
(PS:新建的QQ群,有興趣可以加入一起討論:Android群:322599434)
1、Android解析XML方法
Android里面讀取XML文件有3種方法,其中兩種是解析XML的常規方法:SAX和文檔對象模型方法。以前我寫C++的時候,最常用的是文檔對象模型方法,因為這個方法遍歷數據很方便,缺點是會把整個文件加載到內存,構建一個文檔的樹模型。對於數據量比較大的文件,比較耗內存。以前就經常使用TinyXML的解析庫,我在博客園第一篇文章就是說如何使用TinyXML庫,O(∩_∩)O哈哈~
SAX方法是事件驅動模型,也就是解析到哪個節點會回調相應方法,你需要做的就是在相應的方法里面編寫你的解析代碼,這個有點是解析速度快,而且不耗內存,不過需要你解析完整個文件。查找靈活性沒有文檔對象模型方便。
Android支持上述兩種方法,TinyXML的解析庫也集成在Android里面。除了上面兩種方法,Android自己修改了一種新的方法來解析XML文件——XmlPullParser,這個新方法是基於SAX方法改進的。傳統SAX是需要解析完整個XML文件,而XmlPullParser是可以中途中斷,停止解析。也就是說只要你獲取了你想要的信息,你就可以停止XML的解析工作,因此速度效率上都不錯。
既然是Android官方的方法,這次就使用XmlPullParser來作為XML的解析(我這里數據量不大,用任何一種方法差別不大)。
2、定義XML數據格式
首先我們需要定義我們保存電台數據的XML格式,這是我定義的一種保存電台類型,以及電台類型下面具體電台數據的XML格式,<ChannelType>標簽代表是什么類型的電台,包含了ID、名稱、圖標、級別等信息。
<RadioChannel>是具體的電台數據標簽,保存了電台名稱、圖標、以及URL等重要信息。
//Edited by mythou
//http://www.cnblogs.com/mythou/
<ChannelType ID="1" name="推薦電台" Icon="fm_icon" Level="1"> <RadioChannel ID="001" name="貓撲電台" Icon="default_channel_icon" Level="2" URL="mms://ting.mop.com/mopradio" /> <RadioChannel ID="002" name="國際電台懷舊金曲" Icon="default_channel_icon" Level="2" URL="mms://live.cri.cn/oldies/" /> <RadioChannel ID="003" name="國際電台都市流行" Icon="default_channel_icon" Level="2" URL="mms://live.cri.cn/pop/" /> </ChannelType>
3、使用Pull解析XML
//Edited by mythou
//http://www.cnblogs.com/mythou/
public boolean getRadioListData(InputStream is, ArrayList<RadioChannelData> ChannelTypeList, ArrayList<ArrayList<RadioChannelData>> finalChanneldata) throws Exception { Log.d(TAG, "parse InputStream="+is); //臨時電台類型 RadioChannelData tempChannelTypeItem = null; //臨時電台數據對象 RadioChannelData tempChannelItem = null; //保存每個頻道類型里面具體電台數據 ArrayList<RadioChannelData> channelDataList = null; //顯示ChannelType string String channelTypeString=""; //由android.util.Xml創建一個XmlPullParser實例 XmlPullParser parser = Xml.newPullParser(); //設置輸入流 並指明編碼方式 parser.setInput(is, "UTF-8"); int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: //處理文檔開始 break; case XmlPullParser.START_TAG: if (parser.getName().equals("ChannelType")) { //電台類型信息 tempChannelTypeItem = new RadioChannelData(); tempChannelTypeItem.setChannelID(parser.getAttributeValue(0)); tempChannelTypeItem.setChannelName(parser.getAttributeValue(1)); tempChannelTypeItem.setChannelICON(parser.getAttributeValue(2)); tempChannelTypeItem.setLevel(Integer.valueOf(parser.getAttributeValue(3))); //創建每個類型下的列表 channelDataList = new ArrayList<RadioChannelData>(); } else if (parser.getName().equals("RadioChannel")) { //具體電台信息 tempChannelItem = new RadioChannelData(); tempChannelItem.setChannelID(parser.getAttributeValue(0)); tempChannelItem.setChannelName(parser.getAttributeValue(1)); tempChannelItem.setChannelICON(parser.getAttributeValue(2)); tempChannelItem.setLevel(Integer.valueOf(parser.getAttributeValue(3))); tempChannelItem.setChannelURL(parser.getAttributeValue(4)); } break; case XmlPullParser.END_TAG: if (parser.getName().equals("ChannelType")) { //電台類型列表保存 ChannelTypeList.add(tempChannelTypeItem); tempChannelTypeItem = null; //把每個類型電台列表加入到總數據列表 finalChanneldata.add(channelDataList); channelDataList = null; } else if (parser.getName().equals("RadioChannel")) { channelDataList.add(tempChannelItem); tempChannelItem = null; } break; case XmlPullParser.END_DOCUMENT: break; } eventType = parser.next(); } //Test mythou 打印讀取的數據 Log.d(TAG, "Print all radio channel Type----->"+ChannelTypeList.toString()); Log.d(TAG, "Print all radio final channel data----->"+finalChanneldata.toString()); return true; }
上面代碼是我用來解析XML的代碼,解析的數據保存到對應的ArrayList里面,當然我在程序里面也定義了響應的數據格式類用來保存數據,使用Pull解析XML很方便也很簡單,這里不做詳細介紹,對此不了解的朋友可以去查看相關文檔,個人感覺使用Pull解析文檔比使用文檔對象模型要方便,起碼遍歷一次數據要快捷很多。
補充一點,我這里的圖片文件只保存了圖片文件的名字(不帶后綴),我在程序里面會根據圖片名稱讀取Drawable里面的圖片資源。
界面數據相關的就講到這里,下一次會講解如何控制播放,也就是一個播放器的核心。
系列文章:
Android 開發自己的網絡收音機1——功能要求及設計方案
Android 開發自己的網絡收音機2——電台列表(SlidingMenu側滑欄)
Android 開發自己的網絡收音機3——電台分類(ExpandableListView)
Edited by mythou
原創博文,轉載請標明出處:http://www.cnblogs.com/mythou/p/3231184.html