Android客户端访问网络时,volley与okhttp和volley区别,哪一个更好

Network marketing
北京企商在线数据通信科技有限公司在国内最早从事服务器租用业务、最早推出多功能虚拟主机业务、最早运营本地域外的数据中心、最早全权运营固网运营商数据中心的公司
Network marketing
Android 网络--我是怎么做的: Volley+OkHttp+Https
发布时间: 14:26
Volley 已经发布很长时间了, 也已被广泛应用, 相关教程到处都是. 本文只说两个值得注意的地方.
本文讲解部分比较少, 请参阅提供的相关链接. 完整的实现代码在&Github dodocat/AndroidNetworkDemo&可能看起来比这里更清晰.
使用 OkHttp 作为传输层的实现.
Volley 默认根据 Android 系统版本使用不同的 Http 传输协议实现.
在 Android 3.0 以上 Volley 使用&ApacheHttpStack&作为传输协议, 在2.3 及以下使用&HttpURLConnection&作为传输层协议
OkHttp 相较于其它的实现有以下的优点.
支持SPDY,允许连接同一主机的所有请求分享一个socket。 如果SPDY不可用,会使用连接池减少请求延迟。 使用GZIP压缩下载内容,且压缩操作对用户是透明的。 利用响应缓存来避免重复的网络请求。 当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。 如果你的服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。
因此使用 OkHttp 作为替代是好的选择.
1.首先用 OkHttp 实现一个新的&HurlStack&用于构建 Volley 的 requestQueue.
2.然后使用 OkHttpStack 创建新的 Volley requestQueue.
这样就行了.
使用 Https
作为一个有节操的开发者应该使用 Https 来保护用户的数据, Android 开发者网站上文章Security with HTTPS and SSL做了详尽的阐述.
OkHttp 自身是支持 Https 的. 参考文档&OkHttp Https, 直接使用上面的&OkHttpStack&就可以了, 但是如果遇到服务器开发哥哥使用了自签名的证书(不要问我为什么要用自签名的), 就无法正常访问了.
网上有很多文章给出的方案是提供一个什么事情都不做的TrustManager&跳过&SSL&的验证, 这样做很容受到攻击, Https 也就形同虚设了.
我采用的方案是将自签名的证书打包入 APK 加入信任.
应用难以逆向, 应用不再依赖系统的 trust store, 使得 Charles 抓包等工具失效. 要分析应用 API 必须反编译 APK. 不用额外购买证书, 省钱....
证书部署灵活性降低, 一旦变更证书必须升级程序.
以最著名的自签名网站12306为例说明
1.导出证书
将证书转为 bks 格式
2.下载最新的bcprov-jdk, 执行下面的命令. storepass 是导出密钥文件的密码.
3.将导出的 kyfw.bks 文件放入 res/raw 文件夹下.
4.创建&SelfSignSslOkHttpStack
5.然后用&SelfSignSslOkHttpStack&创建 Volley 的 RequestQueue.
6.我们来试一试, 用上一步穿件的 RequestQueue 替换掉原来的, 然后发请求试试.
注:相关网站建设技巧阅读请移步到建站教程频道。
Network marketing
版权所有:北京企商在线数据通信科技有限公司 CopyRight 2000-.CN ,Inc. All Rights reserved
企商在线通过ISO9001国际标准质量体系认证京ISP号 京B2- 京ICP备020429号 京ICP证041498号 京公网安备号
投诉热线:137-Android客户端访问网络时,volley与okHttp,哪一个更好
o &nbsp,&nbsp&nbsp,&nbsp
客户端与服务器经常需要相互交换数据,为了达到更好的效果,应该选择哪一种框架呢,现在比较好的有volley和okHttp,应该选择哪一种呢?
volley更好一点
关于伯乐小组
这里有好的话题,有启发的回复和值得信任的圈子。
新浪微博:
推荐微信号
(加好友请注明来意)
- 好的话题、有启发的回复、值得信赖的圈子
- 分享和发现有价值的内容与观点
- 为IT单身男女服务的征婚传播平台
- 优秀的工具资源导航
- 翻译传播优秀的外文文章
- 国内外的精选博客文章
- UI,网页,交互和用户体验
- 专注iOS技术分享
- 专注Android技术分享
- JavaScript, HTML5, CSS
- 专注Java技术分享
- 专注Python技术分享
& 2016 伯乐在线Android 使用OkHttp扩展Volley
我们先来回忆一下Volley的用法,使用Volley前,我们一般会先构造出一个RequestQueue,然后不断往该对象中添加请求Request,之后Volley便会进行调度,至于走缓存还是走网络这就看就没有请求过了。而构造RequestQueue的方法如下。
Volley.newRequestQueue(mContext);
而该方法,内部实际上是调用了两个参数的重载方法
public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, null);
我们看下两个参数的重载方法的实现。
private static final String DEFAULT_CACHE_DIR =
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = volley/0;
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + / + info.versionC
} catch (NameNotFoundException e) {
if (stack == null) {
if (Build.VERSION.SDK_INT &= 9) {
stack = new HurlStack();
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-/2011/09/androids-http-clients.
stack = new HttpClientStack(HttpClient.newInstance(userAgent));
Network network = new BasicNetwork(stack);
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start();
在该方法中,进行了以下几步的操作
创建缓存目录,即第一行代码实现的内容。 获得了userAgent,默认情况下是volley/0,如果能够获取到包名,则会被重写为包名/版本号 然后根据第二个入参HttpStack,判断是否为空,其实我们默认的构造RequestQueue中就是传了一个null,如果不为null,则使用参数,如果为null,则根据android的版本进行判断,如果系统版本大于等于9,则使用HurlStack,如果系统版本小于9,则使用HttpClientStack 之后构造Network和Cache对象,将它们传入RequestQueue的构造函数中构造RequestQueue对象,调用该对象的start方法开始死循环,在该循环中如果消息队列中有新的请求则会进行处理。
在这个过程中我们需要关心的是HurlStack和HttpClientStack到底是什么。其实这两个对象都是实现了HttpStack接口的。该接口的定义如下。
public interface HttpStack {
public HttpResponse performRequest(Request request, Map additionalHeaders)
throws IOException, AuthFailureE
该方法中的逻辑需要实现根据参数去完成一个请求,并返回请求结果。我们需要根据这两个实现类,去仿一个OkHttp的实现类,首先我们看一下HurlStack的实现。也就是通过HttpUrlConnection实现的
public HttpResponse performRequest(Request request, Map additionalHeaders)
throws IOException, AuthFailureError {
String url = request.getUrl();
HashMap map = new HashMap();
map.putAll(request.getHeaders());
map.putAll(additionalHeaders);
if (mUrlRewriter != null) {
String rewritten = mUrlRewriter.rewriteUrl(url);
if (rewritten == null) {
throw new IOException(URL blocked by rewriter:
URL parsedUrl = new URL(url);
HttpURLConnection connection = openConnection(parsedUrl, request);
for (String headerName : map.keySet()) {
connection.addRequestProperty(headerName, map.get(headerName));
setConnectionParametersForRequest(connection, request);
// Initialize HttpResponse with data from the HttpURLConnection.
ProtocolVersion protocolVersion = new ProtocolVersion(HTTP, 1, 1);
int responseCode = connection.getResponseCode();
if (responseCode == -1) {
// -1 is returned by getResponseCode() if the response code could not be retrieved.
// Signal to the caller that something was wrong with the connection.
throw new IOException(Could not retrieve response code from HttpUrlConnection.);
StatusLine responseStatus = new BasicStatusLine(protocolVersion,
connection.getResponseCode(), connection.getResponseMessage());
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
if (hasResponseBody(request.getMethod(), responseStatus.getStatusCode())) {
response.setEntity(entityFromConnection(connection));
for (Entry& header : connection.getHeaderFields().entrySet()) {
if (header.getKey() != null) {
Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
response.addHeader(h);
首先拿到url,新建了一个Map对象,往该map对象中放入了请求头的内容,请求头来自两个地方,一个是入参Request中,通过request.getHeaders()获得,一个是入参additionalHeaders中,直接add进去即可
然后会判断一个叫mUrlRewriter的变量是否为空,如果不为空,则调用它的rewriteUrl方法返回新的url,其实它是一个接口,其定义如下,默认情况下这个变量是空,所以这一过程不会被调用。
public interface UrlRewriter {
* Returns a URL to use instead of the provided one, or null to indicate
* this URL should not be used at all.
public String rewriteUrl(String originalUrl);
根据url创建URL对象 通过openConnection方法获得了一个HttpURLConnection对象
protected HttpURLConnection createConnection(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
private HttpURLConnection openConnection(URL url, Request request) throws IOException {
HttpURLConnection connection = createConnection(url);
int timeoutMs = request.getTimeoutMs();
connection.setConnectTimeout(timeoutMs);
connection.setReadTimeout(timeoutMs);
connection.setUseCaches(false);
connection.setDoInput(true);
// use caller-provided custom SslSocketFactory, if any, for HTTPS
if (https.equals(url.getProtocol()) && mSslSocketFactory != null) {
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
在该方法中的操作,主要是打开一个连接,设置超时时间,SSLSocketFactory,是否使用缓存等内容。
然后通过一个for循环往获得的HttpsURLConnection对象中添加请求头,也就是刚才的map
调用setConnectionParametersForRequest设置请求方法和请求体
static void setConnectionParametersForRequest(HttpURLConnection connection,
Request request) throws IOException, AuthFailureError {
switch (request.getMethod()) {
case Method.DEPRECATED_GET_OR_POST:
// This is the deprecated way that needs to be handled for backwards compatibility.
// If the request's post body is null, then the assumption is that the request is
Otherwise, it is assumed that the request is a POST.
byte[] postBody = request.getPostBody();
if (postBody != null) {
// Prepare output. There is no need to set Content-Length explicitly,
// since this is handled by HttpURLConnection using the size of the prepared
// output stream.
connection.setDoOutput(true);
connection.setRequestMethod(POST);
connection.addRequestProperty(HEADER_CONTENT_TYPE,
request.getPostBodyContentType());
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(postBody);
out.close();
case Method.GET:
// Not necessary to set the request method because connection defaults to GET but
// being explicit here.
connection.setRequestMethod(GET);
case Method.DELETE:
connection.setRequestMethod(DELETE);
case Method.POST:
connection.setRequestMethod(POST);
addBodyIfExists(connection, request);
case Method.PUT:
connection.setRequestMethod(PUT);
addBodyIfExists(connection, request);
case Method.HEAD:
connection.setRequestMethod(HEAD);
case Method.OPTIONS:
connection.setRequestMethod(OPTIONS);
case Method.TRACE:
connection.setRequestMethod(TRACE);
case Method.PATCH:
connection.setRequestMethod(PATCH);
addBodyIfExists(connection, request);
throw new IllegalStateException(Unknown method type.);
private static void addBodyIfExists(HttpURLConnection connection, Request request)
throws IOException, AuthFailureError {
byte[] body = request.getBody();
if (body != null) {
connection.setDoOutput(true);
connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(body);
out.close();
该方法会会根据请求的方法调用setRequestMethod设置对应的字符串,并且如果是POST,PUT,PATCH方法,则会调用addBodyIfExists方法设置请求体
之后是新建一个ProtocolVersion对象,传的是HTTP 1.1 获得响应码,如果为-1则扔出异常 构造响应状态行StatusLine 构造响应体,会根据hasResponseBody函数判断是否有响应体内容,如果有则进行设置。
private static boolean hasResponseBody(int requestMethod, int responseCode) {
return requestMethod != Request.Method.HEAD
&& !(HttpStatus.SC_CONTINUE &= responseCode && responseCode & HttpStatus.SC_OK)
&& responseCode != HttpStatus.SC_NO_CONTENT
&& responseCode != HttpStatus.SC_NOT_MODIFIED;
private static HttpEntity entityFromConnection(HttpURLConnection connection) {
BasicHttpEntity entity = new BasicHttpEntity();
InputStream inputS
inputStream = connection.getInputStream();
} catch (IOException ioe) {
inputStream = connection.getErrorStream();
entity.setContent(inputStream);
entity.setContentLength(connection.getContentLength());
entity.setContentEncoding(connection.getContentEncoding());
entity.setContentType(connection.getContentType());
之后将响应头添加到HttpResponse对象中去,并返回这个对象
整个过程其实也是相当简单的,接下来看HttpClientStack的实现,该实现和HurlStack十分相似。
public HttpResponse performRequest(Request request, Map additionalHeaders)
throws IOException, AuthFailureError {
HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
addHeaders(httpRequest, additionalHeaders);
addHeaders(httpRequest, request.getHeaders());
onPrepareRequest(httpRequest);
HttpParams httpParams = httpRequest.getParams();
int timeoutMs = request.getTimeoutMs();
// TODO: Reevaluate this connection timeout based on more wide-scale
// data collection and possibly different for wifi vs. 3G.
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
return mClient.execute(httpRequest);
首先调用createHttpRequest方法设置请求的内容
static HttpUriRequest createHttpRequest(Request request,
Map additionalHeaders) throws AuthFailureError {
switch (request.getMethod()) {
case Method.DEPRECATED_GET_OR_POST: {
// This is the deprecated way that needs to be handled for backwards compatibility.
// If the request's post body is null, then the assumption is that the request is
Otherwise, it is assumed that the request is a POST.
byte[] postBody = request.getPostBody();
if (postBody != null) {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());
entity = new ByteArrayEntity(postBody);
postRequest.setEntity(entity);
return postR
return new HttpGet(request.getUrl());
case Method.GET:
return new HttpGet(request.getUrl());
case Method.DELETE:
return new HttpDelete(request.getUrl());
case Method.POST: {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(postRequest, request);
return postR
case Method.PUT: {
HttpPut putRequest = new HttpPut(request.getUrl());
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(putRequest, request);
return putR
case Method.HEAD:
return new HttpHead(request.getUrl());
case Method.OPTIONS:
return new HttpOptions(request.getUrl());
case Method.TRACE:
return new HttpTrace(request.getUrl());
case Method.PATCH: {
HttpPatch patchRequest = new HttpPatch(request.getUrl());
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(patchRequest, request);
return patchR
throw new IllegalStateException(Unknown request method.);
private static void setEntityIfNonEmptyBody(HttpEntityEnclosingRequestBase httpRequest,
Request request) throws AuthFailureError {
byte[] body = request.getBody();
if (body != null) {
HttpEntity entity = new ByteArrayEntity(body);
httpRequest.setEntity(entity);
这一步,和HurlStack中的setConnectionParametersForRequest的作用是类似的
根据上一步的返回结果HttpUriRequest 对象,调用addHeaders对该对象设置请求头,请求头的来源和HurlStack是一样的
private static void addHeaders(HttpUriRequest httpRequest, Map headers) {
for (String key : headers.keySet()) {
httpRequest.setHeader(key, headers.get(key));
设置超时时间 然后调用HttpClient对象的execute方法,获得HttpResponse对象
可以从上面两个类中看到很多类似的地方
设置请求头 设置请求方法和请求体 设置超时时间等参数 设置响应头和响应体
根据这些步骤,我们写一个使用OkHttp实现的HttpStack的实现类。首先创建类OkHttpStack,实现HttpStack接口
public class OkHttpStack implements HttpStack {
public HttpResponse performRequest(Request request, Map additionalHeaders) throws IOException, AuthFailureError {
提供一个构造函数,传入OkHttpClient 对象
private final OkHttpClient mOkHttpC
public OkHttpStack(OkHttpClient okHttpClient) {
if (okHttpClient == null) {
throw new IllegalArgumentException(OkHttpClient can't be null);
mOkHttpClient = okHttpC
然后实现performRequest方法,首先我们设置一下超时时间
OkHttpClient client = mOkHttpClient.clone();
int timeoutMs = request.getTimeoutMs();
client.setConnectTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setReadTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setWriteTimeout(timeoutMs, TimeUnit.MILLISECONDS);
为了不对外部的OkHttpClient 造成影响,我们这里调用了clone方法克隆了一个。当然也可以直接使用原对象,即
OkHttpClient client = mOkHttpC
int timeoutMs = request.getTimeoutMs();
client.setConnectTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setReadTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setWriteTimeout(timeoutMs, TimeUnit.MILLISECONDS);
接下来设置请求头,请求头的来源有两个,上面已经解析过了。
com.squareup.okhttp.Request.Builder builder=new com.squareup.okhttp.Request.Builder();
builder.url(request.getUrl());
Map headers=request.getHeaders();
for(String name:headers.keySet()){
builder.addHeader(name,headers.get(name));
for(String name:additionalHeaders.keySet()){
builder.addHeader(name,additionalHeaders.get(name));
设置请求头完毕后自然就是请求方法和请求体了,为了保持命名的约定,还是使用setConnectionParametersForRequest函数名,其实现如下
static void setConnectionParametersForRequest(com.squareup.okhttp.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));
case Request.Method.GET:
builder.get();
case Request.Method.DELETE:
builder.delete();
case Request.Method.POST:
builder.post(createRequestBody(request));
case Request.Method.PUT:
builder.put(createRequestBody(request));
case Request.Method.HEAD:
builder.head();
case Request.Method.OPTIONS:
builder.method(OPTIONS,null);
case Request.Method.TRACE:
builder.method(TRACE,null);
case Request.Method.PATCH:
builder.patch(createRequestBody(request));
throw new IllegalStateException(Unknown method type.);
内部还调用了createRequestBody方法设置请求体,其实现如下
private static RequestBody createRequestBody(Request r) throws AuthFailureError{
final byte[] body = r.getBody();
if (body == null)
return RequestBody.create(MediaType.parse(r.getBodyContentType()), body);
设置完毕后,自然就是开始请求了
com.squareup.okhttp.Request okRequest=builder.build();
Call call=client.newCall(okRequest);
Response okresponse=call.execute();
请求完毕,对响应头和响应体进行设置。
首先获得请求的协议
private static ProtocolVersion parseProtocol(final Protocol p)
switch (p)
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);
构造响应状态行
BasicStatusLine responseStatus = new BasicStatusLine(
parseProtocol(okresponse.protocol()),
okresponse.code(),
okresponse.message()
设置响应体
BasicHttpResponse response=new BasicHttpResponse(responseStatus);
response.setEntity(entityFromOkHttpResponse(okresponse));
entityFromOkHttpResponse函数的实现如下,包括对响应内容,响应内容长度,响应内容编码,响应类型进行设置
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());
设置响应头
int size=responseHeaders.size();
String name=
String value=
for(int i=0;i
最后返回HttpResponse对象
贴一下全部的代码
public class OkHttpStack implements HttpStack {
private final OkHttpClient mOkHttpC
public OkHttpStack(OkHttpClient okHttpClient) {
if (okHttpClient == null) {
throw new IllegalArgumentException(OkHttpClient can't be null);
mOkHttpClient = okHttpC
public HttpResponse performRequest(Request request, Map additionalHeaders) throws IOException, AuthFailureError {
OkHttpClient client = mOkHttpC
int timeoutMs = request.getTimeoutMs();
client.setConnectTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setReadTimeout(timeoutMs, TimeUnit.MILLISECONDS);
client.setWriteTimeout(timeoutMs, TimeUnit.MILLISECONDS);
com.squareup.okhttp.Request.Builder builder = new com.squareup.okhttp.Request.Builder();
builder.url(request.getUrl());
Map headers = request.getHeaders();
for (String name : headers.keySet()) {
builder.addHeader(name, headers.get(name));
for (String name : additionalHeaders.keySet()) {
builder.addHeader(name, additionalHeaders.get(name));
setConnectionParametersForRequest(builder, request);
com.squareup.okhttp.Request okRequest = builder.build();
Call call = client.newCall(okRequest);
Response okresponse = call.execute();
BasicStatusLine responseStatus = new BasicStatusLine(
parseProtocol(okresponse.protocol()),
okresponse.code(),
okresponse.message()
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
response.setEntity(entityFromOkHttpResponse(okresponse));
Headers responseHeaders = okresponse.headers();
int size = responseHeaders.size();
String name =
String value =
for (int i = 0; i & i++) {
name = responseHeaders.name(i);
if (name != null) {
response.addHeader(new BasicHeader(name, value));
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());
static void setConnectionParametersForRequest(com.squareup.okhttp.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));
case Request.Method.GET:
builder.get();
case Request.Method.DELETE:
builder.delete();
case Request.Method.POST:
builder.post(createRequestBody(request));
case Request.Method.PUT:
builder.put(createRequestBody(request));
case Request.Method.HEAD:
builder.head();
case Request.Method.OPTIONS:
builder.method(OPTIONS, null);
case Request.Method.TRACE:
builder.method(TRACE, null);
case Request.Method.PATCH:
builder.patch(createRequestBody(request));
throw new IllegalStateException(Unknown method type.);
private static ProtocolVersion parseProtocol(final Protocol p) {
switch (p) {
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 RequestBody createRequestBody(Request r) throws AuthFailureError {
final byte[] body = r.getBody();
if (body == null)
return RequestBody.create(MediaType.parse(r.getBodyContentType()), body);
至于用法,也很简单,在创建RequestQueue对象的时候,第二个参数传入我们的OkHttpStack对象即可。
Volley.newRequestQueue(this,new OkHttpStack(new OkHttpClient()));
此外,网上还有一种更加简洁的实现,但是得添加okhttp-urlconnection依赖
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
该实现不是通过实现HttpStack接口实现的,而是继承HurlStack类实现的
public class SimpleOkHttpStack extends HurlStack {
private final OkUrlFactory okUrlF
public SimpleOkHttpStack() {
this(new OkHttpClient());
public SimpleOkHttpStack(OkHttpClient okHttpClient) {
if (okHttpClient == null) {
throw new NullPointerException(Client must not be null.);
this.okUrlFactory = new OkUrlFactory(okHttpClient);
protected HttpURLConnection createConnection(URL url) throws IOException {
return okUrlFactory.open(url);
甚至你可以选择继承HttpClientStack ,传入OkHttp内部的OkApacheClient实现类,当然也需要添加依赖
compile 'com.squareup.okhttp:okhttp-apache:2.5.0'
public class SimpleHttpClientStack extends HttpClientStack {
public SimpleHttpClientStack(OkHttpClient client) {
super(new OkApacheClient(client));
基本上所有的扩展方法都说了一遍,第一种是完全自己实现,第二种是选择继承现有的类去实现,这个思路和Androd开发中自定义View的思路基本一致,至于选择哪一种,完全看你自己需要。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

我要回帖

更多关于 volley okhttp整合 的文章

 

随机推荐