1. 程式人生 > >Volley支援HTTP/2

Volley支援HTTP/2

volley暫時是不支援HTTP/2的,這是官方的解釋Does volley Support HTTP/2
不過volley設計的擴充套件性特別好,volley提供的介面HttpStack,可以自己去實現來支援HTTP/2。在Android上,從4.4以後系統就已經支援HTTP/2,但是不穩定,有bug,直到Android5.0才修復bug。第三方庫中,有OkHttp 是已經支援了HTTP/2,所以我們可以使用OkHttp 來實現。
具體實現,可以參考OkHttp3Stack
自己的實現如下:

@SuppressWarnings("deprecation")
public class
OkHttpStack implements HttpStack {
private final OkHttpClient mOkHttpClint; public OkHttpStack(OkHttpClient okHttpClient) { this.mOkHttpClint = okHttpClient; } public OkHttpStack() { mOkHttpClint = new OkHttpClient(); } @Override public HttpResponse performRequest
(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { OkHttpClient.Builder builder = mOkHttpClint.newBuilder(); int timeoutMs = request.getTimeoutMs(); builder.connectTimeout(timeoutMs, TimeUnit.MILLISECONDS); builder.readTimeout(timeoutMs, TimeUnit.MILLISECONDS); builder.writeTimeout(timeoutMs, TimeUnit.MILLISECONDS); okhttp3.Request.Builder requestBuilder = new
okhttp3.Request.Builder(); requestBuilder.url(request.getUrl()); Map<String, String> headers = request.getHeaders(); if (headers != null) { for (String key : headers.keySet()) { String value = headers.get(key); if (TextUtils.isEmpty(value)) { continue; } requestBuilder.addHeader(key, value); } } if (additionalHeaders != null) { for (String key : additionalHeaders.keySet()) { String value = additionalHeaders.get(key); if (TextUtils.isEmpty(value)) { continue; } requestBuilder.addHeader(key, value); } } setConnectionParametersForRequest(requestBuilder, request); okhttp3.Request okRequest = requestBuilder.build(); OkHttpClient okClient = builder.build(); Call call = okClient.newCall(okRequest); Response okResponse = call.execute(); BasicStatusLine statusLine = new BasicStatusLine(parseProtocol(okResponse.protocol()), okResponse.code(), okResponse.message()); BasicHttpResponse httpResponse = new BasicHttpResponse(statusLine); httpResponse.setEntity(entityFromOkHttpResponse(okResponse)); Headers okHeaders = okResponse.headers(); for (int i = 0; i < okHeaders.size(); i++) { String name = okHeaders.name(i); String value = okHeaders.value(i); if (name != null) { httpResponse.addHeader(new BasicHeader(name, value)); } } return httpResponse; } @SuppressWarnings("deprecation") /* package */ private static void setConnectionParametersForRequest( /*HttpURLConnection connection*/ okhttp3.Request.Builder builder, Request<?> request) throws IOException, AuthFailureError { CUtils.logD("OK","---request url : " + request.getUrl()); switch (request.getMethod()) { case Request.Method.DEPRECATED_GET_OR_POST: byte[] postBody = request.getPostBody(); if (postBody != null) { // connection.setRequestMethod("POST"); // addBody(connection, request, postBody); builder.post(RequestBody.create(MediaType.parse(request.getPostBodyContentType()), postBody)); } break; case Request.Method.GET: // Not necessary to set the request method because connection defaults to GET but // being explicit here. // connection.setRequestMethod("GET"); builder.get(); break; case Request.Method.DELETE: // connection.setRequestMethod("DELETE"); builder.delete(); break; case Request.Method.POST: // connection.setRequestMethod("POST"); // addBodyIfExists(connection, request); builder.post(addBodyIfExists(request)); break; case Request.Method.PUT: // connection.setRequestMethod("PUT"); // addBodyIfExists(connection, request); builder.put(addBodyIfExists(request)); break; case Request.Method.HEAD: // connection.setRequestMethod("HEAD"); builder.head(); break; case Request.Method.OPTIONS: // connection.setRequestMethod("OPTIONS"); builder.method("OPTIONS", null); break; case Request.Method.TRACE: // connection.setRequestMethod("TRACE"); builder.method("TRACE", null); break; case Request.Method.PATCH: // connection.setRequestMethod("PATCH"); // addBodyIfExists(connection, request); builder.patch(addBodyIfExists(request)); break; default: throw new IllegalStateException("Unknown method type."); } } private static @Nullable RequestBody addBodyIfExists(Request<?> request) throws AuthFailureError { byte[] body = request.getBody(); if (body == null) { return null; } return RequestBody.create(MediaType.parse(request.getBodyContentType()), body); } private static ProtocolVersion parseProtocol(final Protocol protocol) { switch (protocol) { case HTTP_1_0: return new ProtocolVersion("HTTP", 1, 0); case HTTP_1_1: return new ProtocolVersion("HTTP", 1, 1); case SPDY_3: return new ProtocolVersion("SPDY", 3, 1); case HTTP_2: return new ProtocolVersion("HTTP", 2, 0); } throw new IllegalAccessError("Unkwown protocol"); } private static HttpEntity entityFromOkHttpResponse(Response r) throws IOException { BasicHttpEntity entity = new BasicHttpEntity(); ResponseBody body = r.body(); entity.setContent(body.byteStream()); entity.setContentLength(body.contentLength()); entity.setContentEncoding(r.header("Content-Encoding")); if (body.contentType() != null) { entity.setContentType(body.contentType().type()); } return entity; } }

致敬大佬,努力前行!