1. 程式人生 > >Volley網路通訊框架學習筆記(一)

Volley網路通訊框架學習筆記(一)

1.什麼是Volley

我們平時在開發Android應用的時候不可避免地都需要用到網路技術,而多數情況下應用程式都會使用HTTP協議來發送和接收網路資料。

Android系統中主要提供了兩種方式來進行HTTP通訊,HttpURLConnection和HttpClient,幾乎在任何專案的程式碼中我們都能看到這兩個類的身影,使用率非常高。

不過這兩個類的用法還是稍微有些複雜的,如果不進行適當封裝的話,很容易就會寫出不少重複程式碼。於是乎,一些Android網路通訊框架也就應運而生,比如說AsyncHttpClient,它把HTTP所有的通訊細節全部封裝在了內部,我們只需要簡單呼叫幾行程式碼就可以完成通訊操作了。再比如Universal-Image-Loader,它使得在介面上顯示網路圖片的操作變得極度簡單,開發者不用關心如何從網路上獲取圖片,也不用關心開啟執行緒、回收圖片資源等細節,Universal-Image-Loader已經把一切都做好了。

Android開發團隊也是意識到了有必要將HTTP的通訊操作再進行簡單化,於是在2013年Google I/O大會上推出了一個新的網路通訊框架——Volley,這是在演講上的配圖,是一幅發射火弓箭的圖,有點類似流星,說明Volley比較適合資料量不大但是通訊頻繁的場景
這裡寫圖片描述
Volley可以說是把AsyncHttpClient和Universal-Image-Loader的優點集於了一身,既可以像AsyncHttpClient一樣非常簡單地進行HTTP通訊,也可以像Universal-Image-Loader一樣輕鬆載入網路上的圖片。

除了簡單易用之外,Volley在效能方面也進行了大幅度的調整,它的設計目標就是非常適合去進行資料量不大,但通訊頻繁的網路操作,而對於大資料量的網路操作,比如說下載檔案等,Volley的表現就會非常糟糕。

1.1 Volley引入的背景
在以前,我們可能面臨如下很多麻煩的問題。

比如以前從網上下載圖片的步驟可能是這樣的流程:

在ListAdapter#getView()裡開始影象的讀取。
通過AsyncTask等機制使用HttpURLConnection從伺服器去的圖片資源
在AsyncTask#onPostExecute()裡設定相應ImageView的屬性。
而在Volley下,只需要一個函式即可,詳細見後面的例子。

再比如,螢幕旋轉的時候,有時候會導致再次從網路取得資料。為了避免這種不必要的網路訪問,我們可能需要自己寫很多針對各種情況的處理,比如cache什麼的。

再有,比如ListView的時候,我們滾動過快,可能導致有些網路請求返回的時候,早已經滾過了當時的位置,根本沒必要顯示在list裡了,雖然我們可以通過ViewHolder來保持url等來實現防止兩次取得,但是那些已經沒有必須要的資料,還是會浪費系統的各種資源。

1.2 Volley提供的功能
簡單來說,它提供瞭如下的便利功能:

JSON,影象等的非同步下載;
網路請求的排序(scheduling)
網路請求的優先順序處理
快取
多級別取消請求
和Activity和生命週期的聯動(Activity結束時同時取消所有網路請求)

1.3 Volley作為圖片載入庫
在使用Volley作為圖片載入庫的時候,肯定需要做以下幾件事:

—–>Application中初始化Volley請求佇列
—–>初始化ImageLoader,需要設定ImageCache
—–>需要的時候,呼叫下列語句
getInstance().getImageLoader().get(url, new ImageLoader.ImageListener())

2.在Android Studio中如何匯入和使用

Android Studio的配置指導資料比較少,去stackoverflow上找到的。
親測可用,點選下面地址下載JAR包,拷貝到你的Libs下,右鍵add as library,就可以在gradle中看到語句:compile files(‘libs/volley.jar’)
貼出stackoverflow的方法如下:

Source : AndroidHive

copy theVolley.jar to libs
這裡寫圖片描述

Then

Right Click volley.jar -> Add As Library

enter image description here

在運用之前,先在AndroidManifest中加上網路許可權,畢竟Volley是要訪問網路的

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

2.1簡單使用之StringRequest
我們要做的是:發起一條HTTP請求,然後接收HTTP響應。首先需要獲取到一個RequestQueue物件

RequestQueue mQueue = Volley.newRequestQueue(context); 

RequestQueue內部的設計就是非常合適高併發的,因此我們不必為每一次HTTP請求都建立一個RequestQueue物件,這是非常浪費資源的,基本上在每一個需要和網路互動的Activity中建立一個RequestQueue物件就足夠了。

建立一個StringRequest物件,並加入到RequestQueue這個佇列中

        /**
         *  用stringRequest獲取百度首頁返回資訊
         */
        StringRequest stringRequest = new StringRequest("http://www.baidu.com",
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d("TAG", response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("TAG", error.getMessage(), error);
            }
        });
        mQueue.add(stringRequest);

可以看到,這裡new出了一個StringRequest物件,StringRequest的建構函式需要傳入三個引數,第一個引數就是目標伺服器的URL地址,第二個引數是伺服器響應成功的回撥,第三個引數是伺服器響應失敗的回撥。其中,目標伺服器地址我們填寫的是百度的首頁,然後在響應成功的回撥裡打印出伺服器返回的內容,在響應失敗的回撥裡打印出失敗的詳細資訊。最後,將這個StringRequest物件新增到RequestQueue

執行起來的效果就是LogCat中會打印出百度首頁的一長串HTML程式碼。

不過大家都知道,HTTP的請求型別通常有兩種,GET和POST,剛才我們使用的明顯是一個GET請求,那麼如果想要發出一條POST請求應該怎麼做呢?
StringRequest中還提供了另外一種四個引數的建構函式,其中第一個引數就是指定請求型別的,我們可以使用如下方式進行指定:

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener);

可是這只是指定了HTTP請求方式是POST,那麼我們要提交給伺服器的引數又該怎麼設定呢?很遺憾,StringRequest中並沒有提供設定POST引數的方法,
但是當發出POST請求的時候,Volley會嘗試呼叫StringRequest的父類——Request中的getParams()方法來獲取POST引數,那麼解決方法自然也就有了。
我們只需要在StringRequest的匿名類中重寫getParams()方法,在這裡設定POST引數就可以了,程式碼如下所示:

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {  
    @Override  
    protected Map<String, String> getParams() throws AuthFailureError {  
        Map<String, String> map = new HashMap<String, String>();  
        map.put("params1", "value1");  
        map.put("params2", "value2");  
        return map;  
    }  
};  

2.2簡單使用之JsonRequest的用法
類似於StringRequest,JsonRequest也是繼承自Request類的,不過由於JsonRequest是一個抽象類,因此我們無法直接建立它的例項,那麼只能從它的子類入手了。J**sonRequest有兩個直接的子類,JsonObjectRequest和JsonArrayRequest**,從名字上你應該能就看出它們的區別了吧?一個是用於請求一段JSON資料的,一個是用於請求一段JSON陣列的。
至於它們的用法也基本上沒有什麼特殊之處,先new出一個JsonArrayRequest物件,如下所示:

 /**
         *  用的JsonArrayRequest,查詢http://api.androidhive.info/json/movies.json為國外著名博主給的地址
         */
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest("http://api.androidhive.info/json/movies.json",
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d("TAG", response.toString());
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("TAG", error.getMessage(), error);
            }
        });

        mQueue.add(jsonArrayRequest);

JsonArrayRequest的用法和StringRequest的用法基本上是一樣。Volley的易用之處也在這裡體現出來了,會了一種就可以讓你舉一反三。