最近的一次volley整理出下一个。我以前没有再次遭遇了一些小问题,在该记录:

1、HttpUrlConnection DELETE 信息不能加入body问题:java.net.ProtocolException: DELETE does not support writing

这个能够算是一个系统级的bug,为什么这么说,请看这里,这个问题在java8中才得以解决。没办法直接过去,咱就绕过去。查看HttpUrlConnection,我们发现他是一个抽象类,因此能够试试能不能通过它的其它实现来达到我们的目的。

终于我们决定使用okhttp这个实现。地址为:https://github.com/square/okhttp

接着我们还得去看看volley的源代码,因为我们的app兼容的最低版本号是4.0。因此我们知道终于调用的是HurlStack:

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
...
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
...
}

因此我们仅仅须要将HurlStack的相关代码改动就可以,例如以下:

volley.java

public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
...
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
// old way: stack = new HurlStack();
// http://square.github.io/okhttp/
stack = new HurlStack(null, null, new OkUrlFactory(new OkHttpClient()));
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
...
}

HurlStack.java

/**
* An {@link HttpStack} based on {@link HttpURLConnection}.
*/
public class HurlStack implements HttpStack { private final OkUrlFactory mOkUrlFactory; /**
* @param urlRewriter Rewriter to use for request URLs
* @param sslSocketFactory SSL factory to use for HTTPS connections
* @param okUrlFactory solution delete body(https://github.com/square/okhttp)
*/
public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory, OkUrlFactory okUrlFactory) {
mUrlRewriter = urlRewriter;
mSslSocketFactory = sslSocketFactory;
mOkUrlFactory = okUrlFactory;
}
/**
* Create an {@link HttpURLConnection} for the specified {@code url}.
*/
protected HttpURLConnection createConnection(URL url) throws IOException {
if(null != mOkUrlFactory){
return mOkUrlFactory.open(url);
}
return (HttpURLConnection) url.openConnection();
} @SuppressWarnings("deprecation")
/* package */
static void setConnectionParametersForRequest(HttpURLConnection connection,
Request<? > request) throws IOException, AuthFailureError {
switch (request.getMethod()) {
...
case Method.DELETE:
connection.setRequestMethod("DELETE");
addBodyIfExists(connection, request);
break;
...
default:
throw new IllegalStateException("Unknown method type.");
}
} ...
}

2015-04-26更新:

再次使用到须要使用到okhttp,回头看下上面的代码,不知道当时怎么想的。使用这么复杂的方法引入Okhttp。预计是脑袋进水了。

再来看下这种方法:newRequestQueue(Context context, HttpStack stack),有两个參数:context和HttpStack,这里是要传入自己的HttpStack就好了。

那么我们用OKhttp的实现:

/**
* An {@link com.android.volley.toolbox.HttpStack HttpStack} implementation which
* uses OkHttp as its transport.
*/
public class OkHttpStack extends HurlStack {
private final OkHttpClient client; public OkHttpStack() {
this(new OkHttpClient());
} public OkHttpStack(OkHttpClient client) {
if (client == null) {
throw new NullPointerException("Client must not be null.");
}
this.client = client;
} @Override protected HttpURLConnection createConnection(URL url) throws IOException {
return client.open(url);
}
}

參考:https://gist.github.com/JakeWharton/5616899

2、关于(改动)volley的缓存

volley有完整的一套缓存机制。而眼下我们想做个简单的需求:部分界面(差点儿不会改动的)简单的做一定时间的缓存,研究了下代码发现非常easy改动达到自己的目的(有时间在分析下volley的缓存机制,这个一定要做)。简单来说改动一个地方:request.parseNetworkResponse中的

HttpHeaderParser(此处突然感慨volley的设计TMD灵活了。想怎么改就怎么改)。HttpHeaderParser改动后的代码例如以下:

/**
* 改动后的。用户处理缓存
*/
public class BHHttpHeaderParser { /**
* Extracts a {@link Cache.Entry} from a {@link NetworkResponse}.
*
* @param response The network response to parse headers from
* @return a cache entry for the given response, or null if the response is not cacheable.
*/
public static Cache.Entry parseCacheHeaders(NetworkResponse response, boolean isCustomCache) {
...
if(isCustomCache){
softExpire = now + Config.HTTP_CACHE_TTL;
} else {
if (hasCacheControl) {
softExpire = now + maxAge * 1000;
} else if (serverDate > 0 && serverExpires >= serverDate) {
// Default semantic for Expire header in HTTP specification is softExpire.
softExpire = now + (serverExpires - serverDate);
}
} Cache.Entry entry = new Cache.Entry();
entry.data = response.data;
entry.etag = serverEtag;
entry.softTtl = softExpire;
entry.ttl = entry.softTtl;
entry.serverDate = serverDate;
entry.responseHeaders = headers; return entry;
}
...
}

此处大家能够发现,我们主要是依据自己定义的变量决定怎样改动cache的TTL来达到自己的目的。

3、HttpUrlConnection与PATCH(2015-04-26)

在使用Volley发送PATCH请求的时候,我们可能会遇到这种问题:Unknown method 'PATCH'; must be one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE]。这个时候你的第一反应是什么呢?是Volley不支持PATCH请求吗?换成OkHttp是不是能够呢?查看了下Volley的源代码,在HurlHttp.java中发现例如以下一段:

/* package */
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
// GET. 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();
}
break;
case Method.GET:
// Not necessary to set the request method because connection defaults to GET but
// being explicit here.
connection.setRequestMethod("GET");
break;
case Method.DELETE:
connection.setRequestMethod("DELETE");
break;
case Method.POST:
connection.setRequestMethod("POST");
addBodyIfExists(connection, request);
break;
case Method.PUT:
connection.setRequestMethod("PUT");
addBodyIfExists(connection, request);
break;
case Method.HEAD:
connection.setRequestMethod("HEAD");
break;
case Method.OPTIONS:
connection.setRequestMethod("OPTIONS");
break;
case Method.TRACE:
connection.setRequestMethod("TRACE");
break;
case Method.PATCH:
connection.setRequestMethod("PATCH");
addBodyIfExists(connection, request);
break;
default:
throw new IllegalStateException("Unknown method type.");
}
}

通过这段代码。我们知道,Volley对PATCH还是支持的。在细看下错误这个是有HttpUrlConnection抛出的。因此我们须要在这方面下手。

这里有一个參考:

https://github.com/adriancole/retrofit/commit/e704b800878b2e37f5ac98b0139cb4994618ace0

以后有其它关于volley它被记录在这个摘要。

版权声明:本文博主原创文章,博客,未经同意不得转载。

android网络开源框架volley(五岁以下儿童)——volley一些细节的更多相关文章

  1. Android Bluetooth Stack: Bluedroid(五岁以下儿童):The analysis of A2DP Source

    1. A2DP Introduction The Advanced Audio Distribution Profile (A2DP) defines the protocols and proced ...

  2. 各种Android UI开源框架 开源库

    各种Android UI开源框架 开源库 转 https://blog.csdn.net/zhangdi_gdk2016/article/details/84643668 自己总结的Android开源 ...

  3. Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)

    最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所 ...

  4. (五岁以下儿童)NS3样本演示:桥模块演示样品csma-bridge.cc凝视程序

    (五岁以下儿童)NS3:桥模块演示样品csma-bridge.cc凝视程序 1.Ns3 bridge模csma-bridge.cc演示示例程序的目光 // Network topology // // ...

  5. linux下一个Oracle11g RAC建立(五岁以下儿童)

    linux下一个Oracle11g RAC建立(五岁以下儿童) 四.建立主机之间的信任关系(node1.node2) 建立节点之间oracle .grid 用户之间的信任(通过ssh 建立公钥和私钥) ...

  6. python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹

    python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...

  7. PE文件结构(五岁以下儿童)基地搬迁

    PE文件结构(五岁以下儿童) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 基址重定位 链接器生成一个PE文件时,它会如果程序被装入时使用的默认ImageBase基地址(VC默认 ...

  8. 【转载】android 常用开源框架

    对于Android初学者以及对于我们菜鸟,这些大神们开发的轻量级框架非常有用(更别说开源的了). 下面转载这10个框架的介绍:(按顺序来吧没有什么排名). 一.  Afinal 官方介绍: Afina ...

  9. Git8.3k星,十万字Android主流开源框架源码解析,必须盘

    为什么读源码 很多人一定和我一样的感受:源码在工作中有用吗?用处大吗?很长一段时间内我也有这样的疑问,认为哪些有事没事扯源码的人就是在装,只是为了提高他们的逼格而已. 那为什么我还要读源码呢?一刚开始 ...

随机推荐

  1. python的报错

    1;; //////////////////////////////////////////////////////////////////////////////////////////////// ...

  2. 【u249】新斯诺克

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分 ...

  3. 如何在 BitNami 中创建多个 WEB 应用?(转)

    本文最后更新于2015年7月14日,已超过半年没有更新,如果内容失效,请反馈,谢谢! 如您所知,BitNami 为诸多开源 WEB 应用提供集成环境的一键安装解决方案,像著名的开源 WEB 程序 Wo ...

  4. 使用Verdi理解RTL design

    使用Verdi理解RTL design 接触到一些RTL代码,在阅读与深入理解的过程中的一些思考记录 协议与设计框图 认真反复阅读理解相关协议与设计框图,一个design的设计文档中,设计框图展示了这 ...

  5. Java 并发工具包 java.util.concurrent 大全

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  6. 【codeforces 758C】Unfair Poll

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. ie7span标签float换行悬浮

    项目中,ie8以上都是好好的,就是ie7的布局有问题,span换行漂浮了 <div style="height:20px"> <span style=" ...

  8. PatentTips - Hardware virtualization such as separation kernel hypervisors

    BACKGROUND 1. Field Innovations herein pertain to computer virtualization, computer security and/or ...

  9. [Ramda] Filter an Array Based on Multiple Predicates with Ramda's allPass Function

    In this lesson, we'll filter a list of objects based on multiple conditions and we'll use Ramda's al ...

  10. [Angular] Organizing Your Exports with Barrels

    From: import {LoadUserThreadsEffectService} from "./store/effects/load-user-threads.service&quo ...