大家周末好,九月份就要到来。又会一年的开学季,我也即将结束我的实习,回到学校,进行最后一次实训。
上上星期简单分析了Handle的流程,这星期分析Volley框架的工作流程。说实话,这一个框架我没有用过。只是听过这一个框架可定制性很好,未来在做项目可能会采用这个框架,所以提前了解一下。
介绍
Volley框架主要用于小数据的网络传输,例如请求json,文本,加载图片等等。另外,Volley是开源的,并且采用的泛化的概念去编码的,也就是说我们可以自由的定制属于自己的网络传输格式。
实践应用
我们只需要加上一个架包,下载地址:http://download.csdn.net/download/s2311307/9942216
final ImageView iv = (ImageView) findViewById(R.id.main_image);
RequestQueue rq = Volley.newRequestQueue(this);
ImageRequest imageRequest = new ImageRequest(
"http://img5.imgtn.bdimg.com/it/u=311654880,180533069&fm=26&gp=0.jpg",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
iv.setImageBitmap(bitmap);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("TAG",volleyError.getCause().toString());
iv.setImageResource(R.mipmap.ic_launcher);
}
});
rq.add(imageRequest);
实践应用分为三步。
第一步:获取到处理队列:Volley.newRequestQueue(contect)
第二步:创建请求,请求里引用处理请求的监听、
谷歌已经自带了四种请求供我们调用,根据类型调用即可。事实上,这些基本已经满足了大部分需要了。
第三步:把请求添加到队列里面:rq.add(imageRequest)
就这样,就大功告成了。
进一步思考
上面的请求是图片的加载并且设置到我们空间里,虽然很方便,但是却耗流量。在请求里面,默认是有请求的磁盘缓存的——并且有过期的时间限制,过期时间是由服务器控制的。
ImageRequest与其他Request都是用相同的方式去判断是否要用磁盘缓存的。
Entry entry = this.mCache.get(e.getCacheKey());
if(entry == null) {//没有缓存
e.addMarker("cache-miss");
this.mNetworkQueue.put(e);
} else if(entry.isExpired()) {//缓存过期
e.addMarker("cache-hit-expired");
e.setCacheEntry(entry);
this.mNetworkQueue.put(e);
} else {//有缓存
.........
}
在判断缓存过期的方式是通过entry里一个long类型的ttl变量。
public boolean isExpired() {
return this.ttl < System.currentTimeMillis();
}
而ttl变量的初始化是在HttpHeaderParser类的parseCacheHeaders()中。
public static Entry parseCacheHeaders(NetworkResponse response) {
........
String headerValue = (String)headers.get("Date");
if(headerValue != null) {
serverDate = parseDateAsEpoch(headerValue);
}
.......
String token = entry[i].trim();
maxAge = Long.parseLong(token.substring(8));
.......
headerValue = (String)headers.get("Expires");
if(headerValue != null) {
serverExpires = parseDateAsEpoch(headerValue);
}
.......
//计算时间
if(hasCacheControl) {
softExpire = now + maxAge * 1000L;
} else if(serverDate > 0L && serverExpires >= serverDate) {
softExpire = now + (serverExpires - serverDate);
}
Entry var20 = new Entry();
var20.data = response.data;
var20.etag = serverEtag;
var20.softTtl = softExpire
var20.ttl = var20.softTtl;;//设置时间
var20.serverDate = serverDate;
var20.responseHeaders = headers;
return var20;
}
这样的话,就有很大缺陷。
第一:过期时间由服务器返回的header控制,假如服务器没有考虑到这个方面,那么每一次打开页面都会去请求图片,那就很费流量。
第二:假如服务器考虑到这个方面,那么用户在短时期重复打开一个带图片的页面,在缓存的期间内,要去读取磁盘。这样就比较耗性能!
图片加载器一般的要求是:三级缓存。(先去内存拿,内存没有去磁盘缓存中拿,最后才是网络)
这种方式缺少第一级缓存—内存缓存。所以这种图片加载方式,是不推荐的。
谷歌早就考虑到了,所以有更加便利的,自定义内存缓存的图片加载方式。
独特的图片加载
ImageLoader imageLoader = new ImageLoader(rq, new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String s) {
return null;
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
}
});
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(iv, R.mipmap.ic_launcher, R.mipmap.my);
imageLoader.get("https://img-blog.csdn.net/20160507110203928",imageListener);
ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(iv, R.mipmap.ic_launcher, R.mipmap.my);
imageLoader.get("https://img-blog.csdn.net/20160507110203928",imageListener);
其实,这里的最根本,还是与第一种方式一样,把Request添加到队列里,然后后台线程去处理Request。
咱们一步一步来看。
第一步:获取到队列
第二步:创建图片加载器,参数为:队列和自定义的内存缓存。内存缓存谷歌没有提供默认接口,要自己定义!
第三步:创造回调类,和与上面的监听回调的原理是一样的。
第四步:调用图片加载器的get方法。
好,今天就分析到这里。有兴趣可以看第二篇文章:Volley应用与源码分析(二)
下次见!