1. 程式人生 > >學習筆記(六) 網路程式設計與資料處理

學習筆記(六) 網路程式設計與資料處理

廢話不多說啦,我們直接學習Android中最常使用的網路技術。
在請求網路之前,我們需要在AndroidManifest中宣告訪問網路的許可權:

uses-permission android:name="android.permission.INTERNET"/>

-HttpURLConnection

在Android上傳送HTTP請求的方式一般有兩種,HttpURLConnection和HttpClient,但是老師說HttpClient已經被Google棄用了,而HttpURLConnection能夠更好的處理網頁資料,並且可以減少耗電量。
- 獲得HttpURLConnection的例項
在獲取例項之前,我們需要一個URL物件,將目標的網路地址傳入,然後呼叫Url的openConnection()方法。

URL url=new URL("http://www.baidu.com");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();

至於問什麼要呼叫url的openConnection()方法,Android原始碼說是這個方法通過url返回一個指向資源的連線,所以還要進行強制轉型;
還要設定HTTP請求所使用的方式,在學習Html時,學到了GET和POST兩種方式,其中GET是從伺服器端獲取資料,POST是從伺服器端傳送資料,而且GET方式中表單的附加資訊會出現在URl上,相比於POST會不安全。

            connection.setConnectTimeout(8000);//設定連線超時時間
            connection.setReadTimeout(8000); //設定讀取超時時間
            connection.connect();//開啟http連線

下面就是請求baidu資料的例項:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
new
Thread(new Runnable() { @Override public void run() { //請求網路資料,需要申請許可權 data = requestData(url); } }).start(); } private String requestData(String url_String) { //第一種方法 try { String result=null; URL url=new URL(url_String); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET");//設定http請求所使用的方法 connection.setConnectTimeout(8000);//設定連線超時時間 connection.setReadTimeout(8000); //設定讀取超時時間 connection.connect();//開啟http連線 int response= connection.getResponseCode();//獲取響應狀態嘛 if(response== HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream();//獲取伺服器返回的輸入流 Reader reader = new InputStreamReader(inputStream, "utf-8"); char[] buffer = new char[1024]; reader.read(buffer);//將reader讀到的資料放到char陣列中 result=new String(buffer); } else if(response== HttpURLConnection.HTTP_NOT_FOUND){ result="304 NOT FOUND!"; } else{ result="Error!!"; } return result; } catch (MalformedURLException e) { e.printStackTrace(); Toast.makeText(MainActivity.this,"非法網址",Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } finally { connection.disconnect();//關閉http連線 } return null; }

因為獲取網路資料是一個同步操作,所以我們需要在一個子執行緒中去完成耗時操作;

這裡寫圖片描述

除了使用執行緒,Android還提供一個很好的工具類——AsyncTask,但是它的實現原理還是基於非同步訊息處理機制。AsyncTask是一個抽象類,所以使用它必須用一個子類去繼承,其中必須要重寫的三個方法:onPreExecute() ;doInBackground(String[] params);
onPostExecute(String s);
分別對應三個不同的操作,第一個是在子執行緒之前,即在主執行緒中的操作;第二個是全部在子執行緒中執行;第三個是在子執行緒之後,進行的相關操作;
所以,使用AsyncTask會使我們方便很多,不需要在去考慮非同步訊息處理機制了。

-解析XML格式資料

通過上面的requestData()方法,我們得到了xml資料,但是隻有將資料解析之後才能得到我們想要的資料。
- SAX解析方式

private void parseXML_WithSAX(String xmlData) { //將SAX方式解析XML
        try {
            //先建立工程,在建立一個解析器,然後再有一個xml讀取器,固定的步驟
            SAXParserFactory factory=SAXParserFactory.newInstance();
            XMLReader xmlReader=factory.newSAXParser().getXMLReader();
            SAX_Handler sax_handler=new SAX_Handler();
            //將ContentHandler的例項設定到XMLReader中
            xmlReader.setContentHandler(sax_handler);
            //開始執行解析,
            xmlReader.parse(new InputSource(new StringReader(xmlData)));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

String xmlData就是requestData()所返回的xml資料。
- Pull解析方式
Pull方法相對與SAX方法有點複雜。

private void requestXML_Pull(String data) {  //用Pull方式解析XML
        try {
            XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser=factory.newPullParser();
            xmlPullParser.setInput(new StringReader(data));
            int eventType=xmlPullParser.getEventType();
            String id="";
            String item="";
            while(eventType!=XmlPullParser.END_DOCUMENT){
                String nodename=xmlPullParser.getName();
                switch (eventType){
                    //開始解析某個節點
                    case XmlPullParser.START_TAG:
                        if("id".equals(nodename)){
                         id=xmlPullParser.nextText();
                    }else if("item".equals(nodename)){
                            item=xmlPullParser.nextText();
                        }
                    break;
                    case XmlPullParser.END_TAG:
                        if("app".equals(nodename)){
                            Log.i("TAG","id:"+id);
                            Log.i("TAG","item:"+item);
                    }
                        break;
                    default:break;
                }
                eventType=xmlPullParser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

setInput()方法是將伺服器返回的XML資料傳入,並開始解析。通過getEventType()可以得到當前的解析事件,通過while迴圈進行不斷的解析,getItem()方法是得到當前結點的名字,若結點不是結束節點,next()獲取下一個節點;若節點滿足相應的條件,則呼叫nextText()方法獲取節點中具體的內容。

- 解析JSON格式資料

比起XML,JSON主要優勢是在於它的體積更小,在網路上傳輸的時候可以更省流量。
解析JSON的方法有很多,可以使用官方提供的JSONObject,也可以使用Google的GSON。

private void requestJSON(String xml_json) {//測試JSON
        try {
            result="";
            JSONArray jsonArray=new JSONArray(xml_json);
            for(int i=0;i<jsonArray.length();i++){
                JSONObject jsonobject=jsonArray.getJSONObject(i);
                String id=jsonobject.getString("id");
                String name=jsonobject.getString("name");
                String version=jsonobject.getString("version");
                result = "id:"+id+",name:"+name+",version:"+version+result;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

這裡是解析JSON資料中的id和version,通過requestData()從伺服器獲得返回的JSON資料,然後資料傳入一個JSON陣列中,通過JSONObject物件的getString()方法,返回所對應的資料。

GSON解析JSON資料
Google提供了一個非常簡單的工具,它可以將一段JSON格式的字串自動對映成一個物件,從而不需要我們在去解析。
使用GSONFormat工具(大家可以自行百度),將我們的JSON資料可以自動對映成一個物件,通過物件的方法我們可以得到JSON中的任何資料,非常方便。

Gson gson=new Gson();
                JSon_Bean jSon_bean=gson.fromJson(result,JSon_Bean.class);

JSON_Bean是json資料所影射的類,通過fromJson()方法可以獲得物件,從而可以操作JSON中的所有資料。