Volley框架的使用
所謂Volley,它是2013年Google I/O上發(fā)布的一款網(wǎng)絡(luò)框架,基于Android平臺(tái),能使網(wǎng)絡(luò)通信更快,更簡(jiǎn)單,更健全。
它的優(yōu)點(diǎn):(1)默認(rèn)Android2.3及以上基于HttpURLConnection,2.3以下使用基于HttpClient;(2)符合Http 緩存語(yǔ)義 的緩存機(jī)制(提供了默認(rèn)的磁盤(pán)和內(nèi)存等緩存);(3)請(qǐng)求隊(duì)列的優(yōu)先級(jí)排序;(4)提供多樣的取消機(jī)制;(5)提供簡(jiǎn)便的圖片加載工具(其實(shí)圖片的加載才是我們最為看重的功能);(6)一個(gè)優(yōu)秀的框架。
不足之處也有:它只適合數(shù)據(jù)量小,通信頻繁的網(wǎng)絡(luò)操作,如果是數(shù)據(jù)量大的,像音頻,視頻等的傳輸,還是不要使用Volley的為好。
一、獲得Volley
可以直接從google上git clone下來(lái)
git clone https://android.googlesource.com/platform/frameworks/volley然后生成jar包,導(dǎo)入到自己的項(xiàng)目中使用。注意,這個(gè)庫(kù)要求最低SDK版本為Froyo,即至少要設(shè)置android:minSdkVersion為8以上。
不過(guò)由于google的被墻,所以可能要FQ出去。嫌麻煩的話也可以直接問(wèn)我要jar包。
二、使用Volley
volley里面自帶了很多的工具類,像StringRequest,JsonArrayRequest,JsonObjectRequest,ImageRequest,ClearCacheRequest,這些都是我們平時(shí)經(jīng)常使用的http請(qǐng)求,我們就可以直接把它們拿過(guò)來(lái)用。現(xiàn)在來(lái)一一說(shuō)明這些類的用法吧。
在此之前,先說(shuō)一下Volley中的requestQueue吧,所有的request申請(qǐng)出來(lái)后都是扔到這個(gè)隊(duì)列里處理。
requestQueue = Volley.newRequestQueue(context.getApplicationContext()); ... requestQueue.add(request);這樣Volley就會(huì)幫你處理網(wǎng)絡(luò)通信了。
(1)字符數(shù)據(jù)的處理
StringRequest的網(wǎng)絡(luò)請(qǐng)求返回的是一個(gè)字符串。它有兩個(gè)構(gòu)造函數(shù)
/*** Creates a new request with the given method.** @param method the request {@link Method} to use* @param url URL to fetch the string at* @param listener Listener to receive the String response* @param errorListener Error listener, or null to ignore errors*/public StringRequest(int method, String url, Listener<String> listener,ErrorListener errorListener) {super(method, url, errorListener);mListener = listener;}/*** Creates a new GET request.** @param url URL to fetch the string at* @param listener Listener to receive the String response* @param errorListener Error listener, or null to ignore errors*/public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {this(Method.GET, url, listener, errorListener);}第二個(gè)構(gòu)造函數(shù)相比第一個(gè)少了個(gè)method的參數(shù),所以它是默認(rèn)使用get方法。第一個(gè)構(gòu)造函數(shù)是可以讓我們自己定義請(qǐng)求的方式,method的類型定義在Request類中
/*** Supported request methods.*/public interface Method {int DEPRECATED_GET_OR_POST = -1;int GET = 0;int POST = 1;int PUT = 2;int DELETE = 3;int HEAD = 4;int OPTIONS = 5;int TRACE = 6;int PATCH = 7;}默認(rèn)是get,而除此以外我們使用最多的是post的請(qǐng)求方法。
Get請(qǐng)求:
StringRequest request = new StringRequest( "http://www.baidu.com/", new Response.Listener<String>() { @Override public void onResponse(String arg0) { //收到成功應(yīng)答后會(huì)觸發(fā)這里 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { //出現(xiàn)連接錯(cuò)誤會(huì)觸發(fā)這里 } } );在StringRequest中傳入一個(gè)url,一個(gè)通信成功的觸發(fā)器和一個(gè)通信失敗的觸發(fā)器。
 而post的請(qǐng)求方式如下:
可以通過(guò)復(fù)寫(xiě)里面的方法把數(shù)據(jù)給傳進(jìn)去,不止如此,如果還想對(duì)返回的數(shù)據(jù)進(jìn)行進(jìn)一步的處理,可以在重寫(xiě)下面這個(gè)方法
/*** 可以對(duì)返回的reponse做處理, NetworkResponse里面包括狀態(tài)碼,頭信息,內(nèi)容數(shù)據(jù),是否緩存在本地,花費(fèi)的時(shí)間(ms)等內(nèi)容**/@Overrideprotected Response<String> parseNetworkResponse(NetworkResponse response) {// 比如下面的例子是取頭信息里的cookie數(shù)據(jù)/** String mCookie; * for (String s : response.headers.keySet()) {* if (s.contains("Set-Cookie")) { mCookie =* response.headers.get(s); break; } }*/return super.parseNetworkResponse(response);}與前面兩個(gè)重寫(xiě)方法在通信前調(diào)用不同,這個(gè)方法是在通信結(jié)束后調(diào)用的。
 StringRequest的內(nèi)容就那么多,不是很理解的話可以參考示例來(lái)仔細(xì)琢磨…
JsonArrayRequest是專對(duì)于jsonArray的處理,而JsonObjectRequest是對(duì)jsonObject的處理,所以兩個(gè)區(qū)別不大,所以我這里就主要介紹JsonObjectRequest的使用。
事實(shí)上,使用的方法和StringRequest并沒(méi)有什么大的區(qū)別,舉一反三嘛。
JsonObjectRequest的構(gòu)造函數(shù)也是有兩個(gè),不過(guò)內(nèi)容與StringRequest有一點(diǎn)不同。
public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener)第一個(gè)構(gòu)造函數(shù)的參數(shù)分別為 請(qǐng)求方法,url地址,附帶的jsonObject數(shù)據(jù),成功監(jiān)聽(tīng)器,失敗監(jiān)聽(tīng)器。
第二個(gè)構(gòu)造函數(shù)比第一個(gè)少了method的參數(shù),它默認(rèn)的規(guī)則是:當(dāng)jsonRequest為空時(shí),使用get請(qǐng)求方式,不為空則是使用post方式。
由于構(gòu)造函數(shù)中已經(jīng)有了數(shù)據(jù)傳遞的參數(shù),所以不必在重寫(xiě)getParams()的方法了(重寫(xiě)了也沒(méi)用)。
 基本的調(diào)用方法:
最后只要再把成功監(jiān)聽(tīng)器里拿到的數(shù)據(jù)處理就能使用了。
post傳到服務(wù)器上時(shí)已經(jīng)是json格式,接著在服務(wù)器里處理,返回的也要是json格式的數(shù)據(jù),否則會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)誤(無(wú)法轉(zhuǎn)化成JSONObject格式)。
 (!所以我用php寫(xiě)的后臺(tái)來(lái)接受數(shù)據(jù)時(shí),無(wú)法用$_POST來(lái)接收上傳的數(shù)據(jù))
 最后,別忘了把這些請(qǐng)求加到隊(duì)列中。
(2)圖片數(shù)據(jù)的處理
ImageRequest與前面的request用法差不多,都是把請(qǐng)求扔到RequestQueue隊(duì)列里。
ImageRequest imageRequest = new ImageRequest(url,new Listener<Bitmap>() {@Overridepublic void onResponse(Bitmap bitmap) {// TODO Auto-generated method stub }}, maxWidth, maxHeight, decodeConfig, new ErrorListener() {@Overridepublic void onErrorResponse(VolleyError arg0) {// TODO Auto-generated method stubLog.e(TAG, "ErrorStatus: " + arg0.toString());}});可以看到,ImageRequest的構(gòu)造函數(shù)能接收六個(gè)參數(shù),第一個(gè)參數(shù)就是圖片的URL地址。第二個(gè)參數(shù)是圖片請(qǐng)求成功的回調(diào), 這里我們可以把返回的Bitmap參數(shù)設(shè)置到ImageView中。第三第四個(gè)參數(shù)分別用于指定允許圖片最大的寬度和高度,如果指定的網(wǎng)絡(luò)圖片的寬度或高度大于這里的最大值,則會(huì)對(duì)圖片進(jìn)行壓縮,指定成0的話就表示不管圖片有多大,都不會(huì)進(jìn)行壓縮。第五個(gè)參數(shù)用于指定圖片的顏色屬性,Bitmap.Config下的幾個(gè)常量都可以在這里使用,其中ARGB_8888可以展示最好的顏色屬性,每個(gè)圖片像素占據(jù)4個(gè)字節(jié)的大小,而 RGB_565則表示每個(gè)圖片像素占據(jù)2個(gè)字節(jié)大小。第六個(gè)參數(shù)是圖片請(qǐng)求失敗的回調(diào),這里我們可以在請(qǐng)求失敗時(shí)在ImageView中顯示一張默認(rèn)圖片。
最后,把請(qǐng)求放入隊(duì)列中。
requestQueue.add(request);ImageLoader也可以用于加載網(wǎng)絡(luò)上的圖片,并且它的內(nèi)部也是使用ImageRequest來(lái)實(shí)現(xiàn)的,不過(guò)ImageLoader明顯要比ImageRequest更加高效,因?yàn)樗粌H可以幫我們對(duì)圖片進(jìn)行緩存,還可以過(guò)濾掉重復(fù)的鏈接,避免重復(fù)發(fā)送請(qǐng)求。直接上代碼吧
ImageLoader imageLoader = new ImageLoader(requestQueue,new BitmapCache());//新建一個(gè)ImageLoader,傳入requestQueue和圖片緩存類ImageListener listener = ImageLoader.getImageListener(imageView,default_image, failed_image);//參數(shù)分別為要顯示的圖片控件,默認(rèn)顯示的圖片(用于圖片未下載完時(shí)顯示),下載圖片失敗時(shí)顯示的圖片imageLoader.get(url, listener, maxWidth, maxHeight);//開(kāi)始請(qǐng)求網(wǎng)絡(luò)圖片可以看到,ImageLoader的構(gòu)造函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)就是RequestQueue對(duì)象,第二個(gè)參數(shù)是一個(gè)ImageCache對(duì)象,我們通過(guò)調(diào)用ImageLoader的getImageListener()方法能夠獲取到一個(gè)ImageListener對(duì)象,getImageListener()方法接收三個(gè)參數(shù),第一個(gè)參數(shù)指定用于顯示圖片的ImageView控件,第二個(gè)參數(shù)指定加載圖片的過(guò)程中顯示的圖片,第三個(gè)參數(shù)指定加載圖片失敗的情況下顯示的圖片。最后,調(diào)用ImageLoader的get()方法來(lái)加載圖片。
 圖片緩存類代碼如下:
除了上面的兩種加載圖片以外,volley還提供了一個(gè)繼承ImageView的控件給我們使用。我們可以把NetworkImageView控件放入布局文件中然后就能調(diào)用了。
先從布局中獲得控件的控制權(quán),
networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);最后在設(shè)置一些相關(guān)的屬性
networkImageView.setDefaultImageResId(R.drawable.default_image); networkImageView.setErrorImageResId(R.drawable.failed_image); networkImageView.setImageUrl(url,imageLoader);setImageUrl()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)用于指定圖片的URL地址,第二個(gè)參數(shù)則是前面創(chuàng)建好的ImageLoader對(duì)象。其中的imageLoader需要我們自己創(chuàng)建(就是上一個(gè)圖片加載方法的imageLoader),將其作為參數(shù)傳進(jìn)去。其實(shí)NetworkImageView控件和用ImageLoader加載圖片性質(zhì)上都是一樣的。
(3)自定義數(shù)據(jù)的處理
自定義的網(wǎng)絡(luò)請(qǐng)求可以繼承volley的Request類來(lái)重寫(xiě),比如說(shuō)XML格式的請(qǐng)求。其中最重要的是Request類中的parseNetworkResponse方法。
像StringRequest中的parseNetworkResponse方法
String parsed;try {parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));} catch (UnsupportedEncodingException e) {parsed = new String(response.data);}return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));重點(diǎn)是怎么將response.data轉(zhuǎn)化成相應(yīng)的字符格式。
像JsonObject里面的方法
@Overrideprotected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {try {String jsonString =new String(response.data, HttpHeaderParser.parseCharset(response.headers));return Response.success(new JSONObject(jsonString),HttpHeaderParser.parseCacheHeaders(response));} catch (UnsupportedEncodingException e) {return Response.error(new ParseError(e));} catch (JSONException je) {return Response.error(new ParseError(je));}}先將傳過(guò)來(lái)的數(shù)據(jù)轉(zhuǎn)化成String格式,再根據(jù)情況轉(zhuǎn)成Json或者是XML。
 如我們自定義的XMLRequest可以寫(xiě)成這樣子。
三、結(jié)束語(yǔ)
Volley給我們?cè)诰W(wǎng)絡(luò)傳輸?shù)姆矫嫣峁┝撕艽蟮姆奖?#xff0c;尤其是網(wǎng)絡(luò)圖片加載的部分。除此之外,我們可以從volley的源代碼入手可以學(xué)習(xí)到更多的知識(shí),比如說(shuō)如何構(gòu)建一個(gè)完善的框架,如何使框架具有良好的擴(kuò)展性。所以我建議有空的話可以把源代碼下載過(guò)來(lái)仔細(xì)體味一番…
源碼的分析在下面的文章鏈接中。
參考文章:
 (1) Android Volley完全解析 http://blog.csdn.net/guolin_blog/article/details/17482095
 (2)Android應(yīng)用開(kāi)發(fā):網(wǎng)絡(luò)工具——Volley(一) http://blog.csdn.net/airk000/article/details/38983051
 (3)Android應(yīng)用開(kāi)發(fā):網(wǎng)絡(luò)工具——Volley(二) http://blog.csdn.net/airk000/article/details/39003587
 (4)github上的volley庫(kù)分析 https://github.com/android-cn/android-open-project-analysis/tree/master/volley
Demo地址:這是github上一個(gè)開(kāi)源分析項(xiàng)目(@android-cn)里面一位成員(@grumoon,包括上面的volley庫(kù)分析)所寫(xiě)的一個(gè)volley demo地址 https://github.com/android-cn/android-open-project-demo/tree/master/volley-demo
========================================
作者:cpacm
地址:http://www.cnblogs.com/cpacm/p/4193011.html
總結(jié)
以上是生活随笔為你收集整理的Volley框架的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Android Volley完全解析(一
- 下一篇: springBoot将excel文件数据
