Android6.0删除了一些org.apache.http包中的一些类,所以网上的一些解决方案就会有一点不太合适。下面是我自己写了一个解决方案。
1,首先要导入相应的包:
compile 'com.mcxiaoke.volley:library:1.0.19' compile 'com.squareup.okhttp3:okhttp:3.0.1',
2,重写Volley的Volley类,支持OkHttp3
package com.yyw.volleydemo.volley.utils; import android.content.Context; import com.android.volley.RequestQueue; import com.android.volley.toolbox.DiskBasedCache; import java.io.File; import okhttp3.OkHttpClient; /** * Created by yyw on 2016/1/29. * 重写Volley的Volley类,支持OkHttp3 */ public class Volley3 { public Volley3() { } /** * 创建一个客户端的请求队列 * @param context Context * @param stack OkHttpStack * @return */ public static RequestQueue newRequestQueue(Context context, OkHttpStack stack) { File cacheDir = new File(context.getCacheDir(), "volley");//缓存地址:/data/data/com.yyw.volleydemo/cache/volley if(stack == null) {//如果请求的stack为空就建一个默认的 stack = new OkHttpStackImpl(new OkHttpClient.Builder().build()); } <span style="white-space:pre"> </span>//一个自定义的类,实现NetWork接口</span> BasicNetwork3 network1 = new BasicNetwork3(stack); RequestQueue queue1 = new RequestQueue(new DiskBasedCache(cacheDir), network1); queue1.start(); return queue1; } /** * 创建一个指定请求客户端的请求队列 * @param context 上下文 * @param client OkHttpClient * @return 请求队列 */ public static RequestQueue newRequestQueueByClient(Context context, OkHttpClient client) { return newRequestQueue(context, new OkHttpStackImpl(client)); } /** * 创建一个默认请求客户端的请求队列 * @param context 上下文 * @return */ public static RequestQueue newRequestQueue(Context context) { return newRequestQueue(context, null); } }
3,自定义的一个NetWork 模仿BasicNetwork只是把HttpStack,Response换成我们自定义的或Okhttp3中的
package com.yyw.volleydemo.volley.utils; import android.os.SystemClock; import com.android.volley.AuthFailureError; import com.android.volley.Cache; import com.android.volley.Network; import com.android.volley.NetworkError; import com.android.volley.NetworkResponse; import com.android.volley.NoConnectionError; import com.android.volley.Request; import com.android.volley.RetryPolicy; import com.android.volley.ServerError; import com.android.volley.TimeoutError; import com.android.volley.VolleyError; import com.android.volley.VolleyLog; import com.android.volley.toolbox.ByteArrayPool; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.cookie.DateUtils; import java.io.IOException; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.util.Date; import java.util.HashMap; import java.util.Map; import okhttp3.Headers; import okhttp3.Response; /** * Created by yyw on 2016/1/29. * 自定义的一个NetWork * 模仿BasicNetwork只是把HttpStack,Response换成我们自定义的或Okhttp3中的 */ public class BasicNetwork3 implements Network { protected static final boolean DEBUG; private static int SLOW_REQUEST_THRESHOLD_MS; private static int DEFAULT_POOL_SIZE; protected final OkHttpStack mHttpStack; protected final ByteArrayPool mPool; static { DEBUG = VolleyLog.DEBUG; SLOW_REQUEST_THRESHOLD_MS = 3000; DEFAULT_POOL_SIZE = 4096; } public BasicNetwork3(OkHttpStack httpStack) { this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE)); } public BasicNetwork3(OkHttpStack httpStack, ByteArrayPool pool) { this.mHttpStack = httpStack; this.mPool = pool; } public NetworkResponse performRequest(Request<?> request) throws VolleyError { long requestStart = SystemClock.elapsedRealtime(); while(true) { Response okHttpResponse = null; Object responseContents = null; HashMap responseHeaders = new HashMap(); try { HashMap e = new HashMap(); this.addCacheHeaders(e, request.getCacheEntry()); okHttpResponse = this.mHttpStack.performRequest(request, e); int networkResponse1 = okHttpResponse.code(); Map responseHeaders1 = convertHeaders(okHttpResponse.headers()); if(networkResponse1 == 304) { return new NetworkResponse(304, request.getCacheEntry().data, responseHeaders1, true); } byte[] responseContents1 = okHttpResponse.body().bytes(); long requestLifetime = SystemClock.elapsedRealtime() - requestStart; this.logSlowRequests(requestLifetime, request, responseContents1, networkResponse1); if(networkResponse1 != 200 && networkResponse1 != 204) { throw new IOException(); } return new NetworkResponse(networkResponse1, responseContents1, responseHeaders1, false); } catch (SocketTimeoutException var12) { var12.printStackTrace(); attemptRetryOnException("socket", request, new TimeoutError()); } catch (ConnectTimeoutException var13) { attemptRetryOnException("connection", request, new TimeoutError()); } catch (MalformedURLException var14) { throw new RuntimeException("Bad URL " + request.getUrl(), var14); } catch (IOException var15) { NetworkResponse networkResponse = null; if(okHttpResponse == null) { throw new NoConnectionError(var15); } int statusCode1 = okHttpResponse.code(); VolleyLog.e("Unexpected response code %d for %s", new Object[]{Integer.valueOf(statusCode1), request.getUrl()}); if(responseContents == null) { throw new NetworkError(networkResponse); } networkResponse = new NetworkResponse(statusCode1, (byte[])responseContents, responseHeaders, false); if(statusCode1 != 401 && statusCode1 != 403) { throw new ServerError(networkResponse); } attemptRetryOnException("auth", request, new AuthFailureError(networkResponse)); } } } private void logSlowRequests(long requestLifetime, Request<?> request, byte[] responseContents, int status) { if(DEBUG || requestLifetime > (long)SLOW_REQUEST_THRESHOLD_MS) { VolleyLog.d("HTTP response for request=<%s> [lifetime=%d], [size=%s], [rc=%d], [retryCount=%s]", new Object[]{request, Long.valueOf(requestLifetime), responseContents != null?Integer.valueOf(responseContents.length):"null", Integer.valueOf(status), Integer.valueOf(request.getRetryPolicy().getCurrentRetryCount())}); } } private static void attemptRetryOnException(String logPrefix, Request<?> request, VolleyError exception) throws VolleyError { RetryPolicy retryPolicy = request.getRetryPolicy(); int oldTimeout = request.getTimeoutMs(); try { retryPolicy.retry(exception); } catch (VolleyError var6) { request.addMarker(String.format("%s-timeout-giveup [timeout=%s]", new Object[]{logPrefix, Integer.valueOf(oldTimeout)})); throw var6; } request.addMarker(String.format("%s-retry [timeout=%s]", new Object[]{logPrefix, Integer.valueOf(oldTimeout)})); } private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) { if(entry != null) { if(entry.etag != null) { headers.put("If-None-Match", entry.etag); } if(entry.serverDate > 0L) { Date refTime = new Date(entry.serverDate); headers.put("If-Modified-Since", DateUtils.formatDate(refTime)); } } } private static Map<String, String> convertHeaders(Headers headers) { HashMap result = new HashMap(); for(int i = 0; i < headers.size(); ++i) { result.put(headers.name(i), headers.value(i)); } return result; } }
4,自定义的Stack接口
package com.yyw.volleydemo.volley.utils; import com.android.volley.AuthFailureError; import com.android.volley.Request; import java.io.IOException; import java.util.Map; import okhttp3.Response; /** * Created by yyw on 2016/1/28. * 自定义的Stack接口 */ public interface OkHttpStack { /** * 通过这个方法来去执行请求 * @param var1 volley中的请求 * @param var2 参数 * @return OkHttp3的请求响应 * @throws IOException * @throws AuthFailureError */ Response performRequest(Request<?> var1, Map<String, String> var2) throws IOException, AuthFailureError; }
5,提供默认的OkHttpStack实现类(参考使用OKHttp3替换Volley的底层网络请求)
package com.yyw.volleydemo.volley.utils; import com.android.volley.AuthFailureError; import com.android.volley.Request; import java.io.IOException; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.Response; /** * Created by yyw on 2016/1/29. * 默认的请求Stack实例 */ public class OkHttpStackImpl implements OkHttpStack{ private final OkHttpClient mClient;//提供的可以克隆的OkHttpClient,例如HTTPS请求 public OkHttpStackImpl(OkHttpClient client) { this.mClient = client; } @SuppressWarnings("deprecation") private void setConnectionParametersForRequest (okhttp3.Request.Builder builder, Request<?> request) throws IOException, AuthFailureError { switch (request.getMethod()) { case Request.Method.DEPRECATED_GET_OR_POST: byte[] postBody = request.getPostBody(); if (postBody != null) { builder.post(RequestBody.create (MediaType.parse(request.getPostBodyContentType()), postBody)); } break; case Request.Method.GET: builder.get(); break; case Request.Method.DELETE: builder.delete(); break; case Request.Method.POST: builder.post(createRequestBody(request)); break; case Request.Method.PUT: builder.put(createRequestBody(request)); break; case Request.Method.HEAD: builder.head(); break; case Request.Method.OPTIONS: builder.method("OPTIONS", null); break; case Request.Method.TRACE: builder.method("TRACE", null); break; case Request.Method.PATCH: builder.patch(createRequestBody(request)); break; default: throw new IllegalStateException("Unknown method type."); } } /** * 如果需要对OkHttp的请求体进行修改或者添加一些内容可以在这个地方修改 * @param request * @return * @throws AuthFailureError */ protected RequestBody createRequestBody(Request request) throws AuthFailureError { final byte[] body = request.getBody(); if (body == null) return null; return RequestBody.create(MediaType.parse(request.getBodyContentType()), body); } @Override public Response performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { int timeoutMs = request.getTimeoutMs(); OkHttpClient client = mClient.newBuilder() .readTimeout(timeoutMs, TimeUnit.MILLISECONDS) .connectTimeout(timeoutMs, TimeUnit.MILLISECONDS) .writeTimeout(timeoutMs, TimeUnit.MILLISECONDS) .build(); okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder(); Map<String, String> headers = request.getHeaders(); for (final String name : headers.keySet()) { okHttpRequestBuilder.addHeader(name, headers.get(name)); } for (final String name : additionalHeaders.keySet()) { okHttpRequestBuilder.addHeader(name, additionalHeaders.get(name)); } setConnectionParametersForRequest(okHttpRequestBuilder, request); okhttp3.Request okhttp3Request = okHttpRequestBuilder.url(request.getUrl()).build(); Response okHttpResponse = client.newCall(okhttp3Request).execute(); return okHttpResponse; } }好了在创建RequstQueue的时候只要调用Volley3的方法就可以了。