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的易用之處也在這裡體現出來了,會了一種就可以讓你舉一反三。