最近又把volley拿出来整理了下。之前没有遇到过的一些小问题又来了,在此记录下:
这个可以算是一个系统级的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.");
}
}
...
}
volley有完整的一套缓存机制。而目前我们想做个简单的需求:部分界面(几乎不会改动的)简单的做一定时间的缓存,研究了下代码发现很容易修改达到自己的目的(有时间在分析下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来达到自己的目的。
以后有其他关于volley的总结都记录在此。
android网络开源框架volley(五)——volley的一些细节
原文地址:http://blog.csdn.net/ttdevs/article/details/40260433