本文仅介绍如何使用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));