Android 開源框架 ( 六 ) Volley --- Google的輕量級網絡通信框架
一.Volley介紹
2013年Google I/O大會上推出的一個新的Android網絡通信框架,目標是將HTTP的通信操作再進行簡單化,除了簡單易用之外,Volley在性能方面也進行了大幅度的調整,它的設計目標就是非常適合去進行數據量不大,但通信頻繁的網絡操作,而對於大數據量的網絡操作,比如說下載文件等,Volley的表現就會非常糟糕。
二.Volley使用
1.導入jar包
如果只是用於學習,可以通過gradle引用 compile ‘com.mcxiaoke.volley:library:1.0.19‘ 了解下.但是如果用於項目中,最好下載Google官方的jar包.
compile ‘com.mcxiaoke.volley:library:1.0.19‘
2.授權
<uses-permission android:name="android.permission.INTERNET" />
3.使用JsonObjectRequest get請求方式示例
//1.創建一個請求隊列RequestQueue RequestQueue queue= Volley.newRequestQueue(this); //2.創建StringRequest對象 JsonObjectRequest request=new JsonObjectRequest(url, new Response.Listener<JSONObject>() { @Overridepublic void onResponse(JSONObject jsonObject) { //接收返回數據 Log.e("success",jsonObject.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { } });//3.將請求對象添加到請求隊列中 queue.add(request);
同樣還有一些其他請求:ClearCacheRequest,ImageRequest,JsonArrayRequest,JsonRequest,StringRequest 用法一樣.
1.ClearCacheRequest :A synthetic request used for clearing the cache. 用於清除緩存請求類
2.ImageRequest :A canned request for getting an image at a given URL and calling back with a decoded Bitmap. 通過Url獲取對應解碼位圖decoded BitMap 請求類
3.JsonArrayRequest :A request for retrieving a {@link JSONArray} response body at a given URL. 通過Url返回一個{@ Link JSONArray}Json數組請求類
4.JsonObjectRequest :A request for retrieving a {@link JSONObject} response body at a given URL, allowing for an optional {@link JSONObject} to be passed in as part of the request body. 可以通過Url返回一個{@link JSONObject},也可以使用{@link JSONObject}當做請求Request的傳遞參數.
5.JsonRequest :A request for retrieving a T type response body at a given URL that also optionally sends along a JSON body in the request specified. 通過Url返回一個定義的泛型T ,也可以使用JSON當做請求Request的傳遞參數的類
6.StringRequest :A canned request for retrieving the response body at a given URL as a String. 通過Url返回一個String字符串請求類
4.使用JsonObjectRequest post請求方式示例
Post請求,只需要在Request請求裏,添加一個參數Request.Method.POST : new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() {...});其他部分一樣.
RequestQueue queue= Volley.newRequestQueue(this); JsonObjectRequest request=new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { //接收返回數據 Log.e("success",jsonObject.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { } }); queue.add(request);
通過Request.Method.能看到Volley支持的一些請求方式:
5.HurlStack 與 HttpClientStack 介紹
Volley是官方出的,volley在設計的時候是將具體的請求客戶端做了下封裝,也就是說可以支持HttpUrlConnection, HttpClient.當然也可以自己封裝支持OkHttp.
Volley.java類
if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { //HttpURLConnection 請求方式 stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html //HttpClient 請求方式 stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } }
然後具體看下 HurlStack.java 裏的HttpUrlConnection請求封裝.
/** * An {@link HttpStack} based on {@link HttpURLConnection}. */ public class HurlStack implements HttpStack { private static final String HEADER_CONTENT_TYPE = "Content-Type"; /** * Create an {@link HttpURLConnection} for the specified {@code url}. */ protected HttpURLConnection createConnection(URL url) throws IOException { return (HttpURLConnection) url.openConnection(); } /** * Opens an {@link HttpURLConnection} with parameters. * @param url * @return an open connection * @throws IOException */ private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException { HttpURLConnection connection = createConnection(url); int timeoutMs = request.getTimeoutMs(); connection.setConnectTimeout(timeoutMs); connection.setReadTimeout(timeoutMs); connection.setUseCaches(false); connection.setDoInput(true); // use caller-provided custom SslSocketFactory, if any, for HTTPS if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) { ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory); } return connection; } @SuppressWarnings("deprecation") /* package */ static void setConnectionParametersForRequest(HttpURLConnection connection, Request<?> request) throws IOException, AuthFailureError { switch (request.getMethod()) { case Method.DEPRECATED_GET_OR_POST: // This is the deprecated way that needs to be handled for backwards compatibility. // If the request‘s post body is null, then the assumption is that the request is // GET. Otherwise, it is assumed that the request is a POST. byte[] postBody = request.getPostBody(); if (postBody != null) { // Prepare output. There is no need to set Content-Length explicitly, // since this is handled by HttpURLConnection using the size of the prepared // output stream. connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getPostBodyContentType()); DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.write(postBody); out.close(); } break; case Method.GET: // Not necessary to set the request method because connection defaults to GET but // being explicit here. connection.setRequestMethod("GET"); break; case Method.DELETE: connection.setRequestMethod("DELETE"); break; case Method.POST: connection.setRequestMethod("POST"); addBodyIfExists(connection, request); break; case Method.PUT: connection.setRequestMethod("PUT"); addBodyIfExists(connection, request); break; case Method.HEAD: connection.setRequestMethod("HEAD"); break; case Method.OPTIONS: connection.setRequestMethod("OPTIONS"); break; case Method.TRACE: connection.setRequestMethod("TRACE"); break; case Method.PATCH: connection.setRequestMethod("PATCH"); addBodyIfExists(connection, request); break; default: throw new IllegalStateException("Unknown method type."); } } private static void addBodyIfExists(HttpURLConnection connection, Request<?> request) throws IOException, AuthFailureError { byte[] body = request.getBody(); if (body != null) { connection.setDoOutput(true); connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType()); DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.write(body); out.close(); } } }
在看看HttpClientStack.java 裏的HttpClient的封裝. 註意下哈,HttpClient 已經在Android 6.0 刪除.
/** * An HttpStack that performs request over an {@link HttpClient}. */ public class HttpClientStack implements HttpStack { protected final HttpClient mClient; private final static String HEADER_CONTENT_TYPE = "Content-Type"; /** * Creates the appropriate subclass of HttpUriRequest for passed in request. */ @SuppressWarnings("deprecation") /* protected */ static HttpUriRequest createHttpRequest(Request<?> request, Map<String, String> additionalHeaders) throws AuthFailureError { switch (request.getMethod()) { case Method.DEPRECATED_GET_OR_POST: { // This is the deprecated way that needs to be handled for backwards compatibility. // If the request‘s post body is null, then the assumption is that the request is // GET. Otherwise, it is assumed that the request is a POST. byte[] postBody = request.getPostBody(); if (postBody != null) { HttpPost postRequest = new HttpPost(request.getUrl()); postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType()); HttpEntity entity; entity = new ByteArrayEntity(postBody); postRequest.setEntity(entity); return postRequest; } else { return new HttpGet(request.getUrl()); } } case Method.GET: return new HttpGet(request.getUrl()); case Method.DELETE: return new HttpDelete(request.getUrl()); case Method.POST: { HttpPost postRequest = new HttpPost(request.getUrl()); postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(postRequest, request); return postRequest; } case Method.PUT: { HttpPut putRequest = new HttpPut(request.getUrl()); putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(putRequest, request); return putRequest; } case Method.HEAD: return new HttpHead(request.getUrl()); case Method.OPTIONS: return new HttpOptions(request.getUrl()); case Method.TRACE: return new HttpTrace(request.getUrl()); case Method.PATCH: { HttpPatch patchRequest = new HttpPatch(request.getUrl()); patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(patchRequest, request); return patchRequest; } default: throw new IllegalStateException("Unknown request method."); } } }
Android 開源框架 ( 六 ) Volley --- Google的輕量級網絡通信框架