最近的一次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. storm编程指南

    目录 storm编程指南 (一)创建spout (二)创建split-bolt (三)创建wordcount-bolt (四)创建report-bolt (五)创建topo storm编程指南 @(博 ...

  2. 英特尔投资:7200万美元投资12家创新公司,包括3家中国公司(www.intelcapital.com)

    集微网消息,英特尔投资——英特尔公司全球投资机构,今天在英特尔投资全球峰会上宣布向12家科技创业公司投资超过7200万美元.加上今天宣布的新投资,英特尔投资在2018年投资总额已超过1.15亿美元. ...

  3. MFC切换图片防止闪烁

    处理WM_ERASEBKGND消息,在消息处理函数中return TRUE;

  4. 如何知道刚刚插入数据库那条数据的id

    如何知道刚刚插入数据库那条数据的id 一.总结 一句话总结:这些常见功能各个框架里面都有,可以查看手册,thinkphp里面是$userId = Db::name('user')->getLas ...

  5. NET WinForm 开发所见即所得的 IDE 开发环境

    Github 开源:使用 .NET WinForm 开发所见即所得的 IDE 开发环境(Sheng.Winform.IDE)[2.源代码简要说明]   GitHub:https://github.co ...

  6. 在ArcEngine中使用Geoprocessing工具-执行工具

    转自原文在ArcEngine中使用Geoprocessing工具-执行工具 来解析一下Geoprocessor类的Execute方法,他有两种重载,Execute(IGPProcess, ITrack ...

  7. [Docker] Build Your Own Custom Docker Image

    In this lesson we will cover how to build your own custom Docker image from scratch. We'll walk thro ...

  8. Linux网络编程——原始套接字实例:MAC 头部报文分析

    通过<Linux网络编程——原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? 链路层封包格式 M ...

  9. android studio 2.2 使用cmake编译NDK

    Android studio 2.2 已经进入beta版本,新功能添加众多,NDK编程也得到了简化.官方博客介绍.本文介绍如何使用新版android studio调用 c++代码,为了超级通俗易懂,例 ...

  10. C/C++ 变量的初始化

    局部变量,初始化为垃圾值,局部静态变量初始化为 0: 1. 二维数组 // 作为局部变量 int arr[4]; // 全是垃圾值 int arr[4] = {1}; // 第一个元素为 1,其他默认 ...