Volley应用与源码分析(一)

大家周末好,九月份就要到来。又会一年的开学季,我也即将结束我的实习,回到学校,进行最后一次实训。

上上星期简单分析了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应用与源码分析(二)

下次见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值