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());
}
//一个自定义的类,实现NetWork接口
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 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 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 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 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 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的方法就可以了。