volley完全解析

一、volley是什么?

1、简介

  Volley是Goole在2013年Google I/O大会上推出了一个新的网络通信框架,它是开源的。从名字由来和配图中无数急促的火箭可以看出 Volley 的特点:特别适合数据量小,通信频繁的网络操作。(个人认为 Android 应用中绝大多数的网络操作都属于这种类型)。

  Volley加载图片实现了两级缓存(网络缓存、文件缓存),没有实现内存的缓存。Volley已经把各种异步任务、图片采样都封装好了。内存缓存使用lrucache类实现,需要我们手动添加进去。没有使用软引用缓存。因为4.0之后的android系统已经不推荐使用软引用缓存了。

2、volley的总体设计

这里写图片描述

这里写图片描述

3、volley可以做什么

JSON,图像等的异步下载;
处理get、post等网络请求;
网络请求的排序(scheduling);
网络请求的优先级处理;
缓存;
多级别取消请求;
和Activity和生命周期的联动(Activity结束时同时取消所有网络请求);
等等。

它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

二、图片的三级缓存在volley中的实现

  其实volley可以完全取代我们手写的三级缓存,因为google已经对volley进行了非常好的封装,具体说明如下:

1、volley的推荐用法-单例模式

  使用volley时,我们推荐把volley的使用封装成单例使用。在application中初始化它。具体代码如下:

单例:

package com.ht.xiangqu.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

/**
 * Created by annuo on 2015/6/16.
 */
public class RequestManager {
    private static RequestManager ourInstance;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;


    public static RequestManager createInstance(Context context) {
        if (context != null) {
            if (ourInstance == null) {
                ourInstance = new RequestManager(context);
            } else {
                throw new IllegalArgumentException("Context must be set");
            }
        }
        return ourInstance;
    }

    public static RequestManager getInstance() {
        return ourInstance;
    }

    private RequestManager(Context context) {
        requestQueue = Volley.newRequestQueue(context);
        imageLoader = new ImageLoader(
                requestQueue,
                new ImageLoader.ImageCache() {
                    private LruCache<String, Bitmap> cache
                            = new LruCache<>(20);
                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                }
        );
    }

    public RequestQueue getRequestQueue() {
        return requestQueue;
    }


    public ImageLoader getImageLoader() {
        return imageLoader;
    }

}

application:

package com.ht.xiangqu.util;

import android.app.Application;
import android.util.Log;

/**
 * Created by annuo on 2015/6/16.
 */
public class MainApplation extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        RequestManager.createInstance(getApplicationContext());
        Log.d("nihao", "nihao");
    }
}

2、内存缓存

  只有加载图片的时候才会有内存缓存,对于字符串一般都是之后文件缓存。

  google并没有自动的帮我们实现内存的缓存,需要我们自己手动加入进去。内存缓存在单例类中已经体现了(即LruCache),以后我们每次使用的时候都不必再加入内存缓存。LruCache这个类是Android3.1版本中提供的,如果你是在更早的Android版本中开发,则需要导入android-support-v4的jar包。

3、文件缓存

  volley已经默认帮我们实现了文件的缓存。我们通过源代码看一下:

    /**
     * Constructs a new ImageLoader.
     * @param queue The RequestQueue to use for making image requests.
     * @param imageCache The cache to use as an L1 cache.
     */
    public ImageLoader(RequestQueue queue, ImageCache imageCache) {
        mRequestQueue = queue;
        mCache = imageCache;
    }

  以上代码是imageloader中的一段代码,从中我们可以看到在构造imageloader时,我们已经默认的建立了一个L1级的缓存(文件缓存)。

那volley缓存下来的文件到底在哪呢?见下图:

这里写图片描述

  具体的位置就在如图所示的位置。即data/data/应用程序的包名/volley,如果没有修改volley的缓存位置,默认名字叫volley。

4、图片的二次采样的问题

  其实volley默认的已经帮我们做了图片的二次采样,只是需要我们在进行请求的时候,多加入两个参数。我们一般都忽略了这个问题,最后导致的是不断的OOM。

    /**
     * 这是访问网络图片的核心方法
     * @param requestUrl
     * @param imageListener
     * @param maxWidth
     * @param maxHeight
     * @return
     */
    public ImageContainer get(String requestUrl, ImageListener imageListener,
            int maxWidth, int maxHeight) {
        Request<?> newRequest =
            new ImageRequest(requestUrl, new Listener<Bitmap>() {
                @Override
                public void onResponse(Bitmap response) {
                    onGetImageSuccess(cacheKey, response);
                }
            }, maxWidth, maxHeight,
            Config.RGB_565, new ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    onGetImageError(cacheKey, error);
                }
            });

        mRequestQueue.add(newRequest);
        mInFlightRequests.put(cacheKey,
                new BatchedImageRequest(newRequest, imageContainer));
        return imageContainer;
    }

  以上代码是imageloader的核心方法,其中有两个参数是maxWidth,maxHeight,我们一般都忽略了这两个参数。默认值是0和0,这样二次采样算法就不起作用了,我们得到的图片是从服务器1:1哪来的。但是一般我们设置了这两个参数,就可以得到我们希望的缩小比例的图片。这样就可以完全的避免OOM。

三、volley的其他问题

1、圆角图片的问题

    public static ImageListener getImageListener(final ImageView view,
            final int defaultImageResId, final int errorImageResId) {
        return new ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (errorImageResId != 0) {
                    view.setImageResource(errorImageResId);
                }
            }

            @Override
            public void onResponse(ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    //在这里可以设置,如果想得到圆角图片的画,可以对bitmap进行加工,可以给imageview加一个
                    //额外的参数
                    view.setImageBitmap(response.getBitmap());
                } else if (defaultImageResId != 0) {
                    view.setImageResource(defaultImageResId);
                }
            }
        };
    }

2、listview复用时,解决图片错位的问题

    /**
     * 使用此方法能够解决图片错乱问题
     * @param view
     * @param defaultImageResId
     * @param errorImageResId
     * @param url
     * @return
     */
    public static ImageListener getImageListener(
            final ImageView view,
            final int defaultImageResId,
            final int errorImageResId,
            final String url) {
        return new ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (errorImageResId != 0) {
                    view.setImageResource(errorImageResId);
                }
            }

            @Override
            public void onResponse(ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    //在这里可以设置,如果想得到圆角图片的画,可以对bitmap进行加工,可以给imageview加一个
                    //额外的参数
                    String urlTag = (String) view.getTag();
                    if(urlTag!=null && urlTag.trim().equals(url)){
                        view.setImageBitmap(response.getBitmap());
                    }
                } else if (defaultImageResId != 0) {
                    view.setImageResource(defaultImageResId);
                }
            }
        };
    }

四、volley的具体用法

  关于这块内容,网络上有很多的资料,总之volley使用起来非常的简单,感兴趣的可以去网络上查找相关的资料进行学习。volley的加载速度绝对出乎你的意料。

——知道自己是谁,要什么,能跳多高,而且敢跳,并承受跳了可能失败的所有结果。

  • 0
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值