Android 開發自己的網絡收音機4——讀取XML文件的電台數據


  國內外的電台數據很多,起碼有好幾百,所以把這些數據都寫到代碼里面是不實際的。只能寫成一個數據文件,程序啟動的時候再去加載。保存這些簡單數據,我們肯定會優先使用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 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM