Android volley 使用OkHttp3.0

本文僅介紹如何使用OKHttp3.0實現HttpStack,從而接管volley的網絡請求。

前言:

volley ---- Google出品的android平臺輕量級網絡庫

          優點:擴展性強,請求隊列管理

     基本介紹:http://blog.csdn.net/t12x3456/article/details/9221611/

     github鏡像: https://github.com/mcxiaoke/android-volley

 

okhttp----Square出品的java網絡庫,android4.4以後已作爲默認的HTTP連接實現

       優點:支持SPDY,連接池,傳輸效率的各種優化

     源碼:https://github.com/square/okhttp

       官方wiki:https://github.com/square/okhttp/wiki

 

正文:

OkHttp 3.x相對於2.x,在api以及使用規範上有一些調整,所以在實現HttpStack的時候要做相應的更改,基本用法不變。

參考來源:http://blog.csdn.net/lonewolf521125/article/details/47256475

 

下面直接上代碼,紅色部分關注一下即可。

複製代碼
  1 package com.xxx.xxx;
  2 
  3 import com.android.volley.AuthFailureError;
  4 import com.android.volley.Request;
  5 import com.android.volley.toolbox.HttpStack;
  6 
  7 import org.apache.http.HttpEntity;
  8 import org.apache.http.HttpResponse;
  9 import org.apache.http.ProtocolVersion;
 10 import org.apache.http.StatusLine;
 11 import org.apache.http.entity.BasicHttpEntity;
 12 import org.apache.http.message.BasicHeader;
 13 import org.apache.http.message.BasicHttpResponse;
 14 import org.apache.http.message.BasicStatusLine;
 15 
 16 import java.io.IOException;
 17 import java.util.Map;
 18 import java.util.concurrent.TimeUnit;
 19 
 20 import okhttp3.Call;
 21 import okhttp3.Headers;
 22 import okhttp3.MediaType;
 23 import okhttp3.OkHttpClient;
 24 import okhttp3.Protocol;
 25 import okhttp3.RequestBody;
 26 import okhttp3.Response;
 27 import okhttp3.ResponseBody;
 28 
 29 /**
 30  * The MIT License (MIT)
 31  * <p/>
 32  * Copyright (c) 2015 Circle Internet Financial
 33  * <p/>
 34  * Permission is hereby granted, free of charge, to any person obtaining a copy
 35  * of this software and associated documentation files (the "Software"), to deal
 36  * in the Software without restriction, including without limitation the rights
 37  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 38  * copies of the Software, and to permit persons to whom the Software is
 39  * furnished to do so, subject to the following conditions:
 40  * <p/>
 41  * The above copyright notice and this permission notice shall be included in
 42  * all copies or substantial portions of the Software.
 43  * <p/>
 44  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 45  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 46  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 47  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 48  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 49  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 50  * THE SOFTWARE.
 51  */
 52 
 53 /**
 54  * OkHttp backed {@link com.android.volley.toolbox.HttpStack HttpStack} that
 55  * does not use okhttp-urlconnection
 56  */
 57 public class OkHttpStack implements HttpStack {
 58     
 59     private final OkHttpClient mClient;
 60     
 61     public OkHttpStack(OkHttpClient client) {
 62         this.mClient = client;
 63     }
 64     
 65     @Override
 66     public HttpResponse performRequest(Request<?> request,
 67             Map<String, String> additionalHeaders) throws IOException, AuthFailureError {
 68         
 69         int timeoutMs = request.getTimeoutMs();
 70         // okhttp 3.0以後的版本構建OkHttpClient使用Builder
 71         OkHttpClient.Builder builder = mClient.newBuilder();
 72         builder.connectTimeout(timeoutMs, TimeUnit.MILLISECONDS)
 73                 .readTimeout(timeoutMs, TimeUnit.MILLISECONDS)
 74                 .writeTimeout(timeoutMs, TimeUnit.MILLISECONDS);
 75         OkHttpClient client = builder.build();
 76         
 77         okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder();
 78         okHttpRequestBuilder.url(request.getUrl());
 79         
 80         Map<String, String> headers = request.getHeaders();
 81         for (final String name : headers.keySet()) {
 82             okHttpRequestBuilder.addHeader(name, headers.get(name));
 83         }
 84         for (final String name : additionalHeaders.keySet()) {
 85             // 這裏用header方法,如果有重複的name,會覆蓋,否則某些請求會被判定爲非法
 86             okHttpRequestBuilder.header(name, additionalHeaders.get(name));
 87         }
 88         
 89         setConnectionParametersForRequest(okHttpRequestBuilder, request);
 90         
 91         okhttp3.Request okHttpRequest = okHttpRequestBuilder.build();
 92         Call okHttpCall = client.newCall(okHttpRequest);
 93         Response okHttpResponse = okHttpCall.execute();
 94         
 95         StatusLine responseStatus = new BasicStatusLine(
 96                 parseProtocol(okHttpResponse.protocol()), okHttpResponse.code(),
 97                 okHttpResponse.message());
 98         BasicHttpResponse response = new BasicHttpResponse(responseStatus);
 99         response.setEntity(entityFromOkHttpResponse(okHttpResponse));
100         
101         Headers responseHeaders = okHttpResponse.headers();
102         for (int i = 0, len = responseHeaders.size(); i < len; i++) {
103             final String name = responseHeaders.name(i), value = responseHeaders.value(i);
104             if (name != null) {
105                 response.addHeader(new BasicHeader(name, value));
106             }
107         }
108         
109         return response;
110     }
111     
112     private static HttpEntity entityFromOkHttpResponse(Response r) throws IOException {
113         BasicHttpEntity entity = new BasicHttpEntity();
114         ResponseBody body = r.body();
115         
116         entity.setContent(body.byteStream());
117         entity.setContentLength(body.contentLength());
118         entity.setContentEncoding(r.header("Content-Encoding"));
119         
120         if (body.contentType() != null) {
121             entity.setContentType(body.contentType().type());
122         }
123         return entity;
124     }
125     
126     @SuppressWarnings("deprecation")
127     private static void setConnectionParametersForRequest(
128             okhttp3.Request.Builder builder, Request<?> request) throws IOException,
129             AuthFailureError {
130         switch (request.getMethod()) {
131             case Request.Method.DEPRECATED_GET_OR_POST:
132                 // Ensure backwards compatibility. Volley assumes a request with
133                 // a null body is a GET.
134                 byte[] postBody = request.getPostBody();
135                 if (postBody != null) {
136                     builder.post(RequestBody.create(
137                             MediaType.parse(request.getPostBodyContentType()), postBody));
138                 }
139                 break;
140             case Request.Method.GET:
141                 builder.get();
142                 break;
143             case Request.Method.DELETE:
144                 builder.delete();
145                 break;
146             case Request.Method.POST:
147                 builder.post(createRequestBody(request));
148                 break;
149             case Request.Method.PUT:
150                 builder.put(createRequestBody(request));
151                 break;
152             case Request.Method.HEAD:
153                 builder.head();
154                 break;
155             case Request.Method.OPTIONS:
156                 builder.method("OPTIONS", null);
157                 break;
158             case Request.Method.TRACE:
159                 builder.method("TRACE", null);
160                 break;
161             case Request.Method.PATCH:
162                 builder.patch(createRequestBody(request));
163                 break;
164             default:
165                 throw new IllegalStateException("Unknown method type.");
166         }
167     }
168     
169     private static ProtocolVersion parseProtocol(final Protocol p) {
170         switch (p) {
171             case HTTP_1_0:
172                 return new ProtocolVersion("HTTP", 1, 0);
173             case HTTP_1_1:
174                 return new ProtocolVersion("HTTP", 1, 1);
175             case SPDY_3:
176                 return new ProtocolVersion("SPDY", 3, 1);
177             case HTTP_2:
178                 return new ProtocolVersion("HTTP", 2, 0);
179         }
180         
181         throw new IllegalAccessError("Unkwown protocol");
182     }
183     
184     private static RequestBody createRequestBody(Request r) throws AuthFailureError {
185         byte[] body = r.getBody();
186         if (body == null) {
187             // OkHttp內部默認的的判斷邏輯是POST 不能爲空,這裏做了規避
188             if (r.getMethod() == Request.Method.POST) {
189                 body = "".getBytes();
190             }
191             else {
192                 return null;
193             }
194         }
195         
196         return RequestBody.create(MediaType.parse(r.getBodyContentType()), body);
197     }
198 }
複製代碼

 在volley的調用:

1 OkHttpClient okClient = new OkHttpClient.Builder().build();
2 
3 RequestQueue queue = Volley.newRequestQueue(context, new OkHttpStack(okClient));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章