Volley支持HTTP/2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wxz1179503422/article/details/82251811

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;
    }


}

致敬大佬,努力前行!

猜你喜欢

转载自blog.csdn.net/wxz1179503422/article/details/82251811