Volley的介绍

  • Volley是什么?

    • 2013年Google I/O大会上推出的网络请求和图片加载框架
    • 其优点是api简单,性能优秀
    • 非常适合数据量不大但是通信频繁的网络请求,而对于大数据量的操作,如文本下载,表现则没有那么好
    • Volley内部仍然是使用的HttpURLConnection和HttpClient进行网络请求的,只是对于不同的Android版本进行了响应的切换,2.3之前使用的HttpClient,2.3之后使用的是HttpURLConnection 这是因为在2.3版本之前,HttpURLConnection有一个很严重的bug,当开启请求的时候会造成线程池无法关闭。
  • 为什么用Volley,相比XUtil,Volley解决了以下问题:
    • 当用户finish当前的Activity的时候,而当前Activity正在进行网络请求,Volley支持取消网络请求
    • 当用户旋转屏幕,Activity重新创建,那么同样的网络请求会从新发送,而Volley支持对重复的请求进行缓存
    • 支持多样的网络请求返回封装

3. Volley的使用

  • 首先,引入Volley类库,添加相关权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • Volley中的核心类

    • Request,请求类,有几个实现类

      • StringRequest:请求的时候直接回来一个String
      • JsonObjectRequest:请求的时候直接回来一个JsonObject
      • JsonArrayRequest:请求的时候直接回来一个JsonArray
      • ImageRequest:请求的时候直接回来一个Bitmap
      • 自定义请求:一会我们会结合gson
    • RequestQueue:请求队列,用来执行Request的
    • ImageLoader:图片加载的类
    • NetWorkImageView:继承自ImageView,可以直接加载网络图片
  • 创建请求队列RequestQueue

    RequestQueue queue = Volley.newRequestQueue(this);
  • 使用StringRequest进行请求

    //2.创建网络请求
    StringRequest stringRequest = new StringRequest(url, new Listener<String>() {
    @Override
    public void onResponse(String response) {
    tv_result.setText(response);
    }
    },new MyErrorListener());
    //3.执行请求
    queue.add(stringRequest);
  • 使用JsonRequest进行请求

    //1.创建JsonRequest请求
    JsonObjectRequest joRequest = new JsonObjectRequest(url, null, new Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
    tv_result.setText(response.toString());
    }
    }, new MyErrorListener());
    //2.执行请求
    queue.add(joRequest);
  • 使用JsonArrayRequest进行请求

    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(listUrl, new Listener<JSONArray>() {
    @Override
    public void onResponse(JSONArray response) {
    tv_result.setText(response.toString());
    }
    }, new MyErrorListener());
    queue.add(jsonArrayRequest);
  • 使用ImageRequest进行请求

    ImageRequest imageRequest = new ImageRequest(imageUrl,new Listener<Bitmap>() {
    @Override
    public void onResponse(Bitmap response) {
    iv_result.setImageBitmap(response);
    }
    }, 200, 100, Config.RGB_565, new MyErrorListener());
    queue.add(imageRequest);

4. 加载图片的压缩处理的核心

  • 第一步: 从原图进行等宽高比的采样,采样的值最好是2的倍数,代码如下:

    Options opts = new Options();
    opts.inSampleSize = 4;
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts);
  • 第二步: 根据图片的原始宽高比和控件的宽高比,科学的计算采样比例,代码如下:

    Options opts = new Options();
    opts.inJustDecodeBounds = true;//设置只解析图片的边界参数,即宽高
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts);
    //科学计算图片所需的采样比例
    opts.inSampleSize = caculateSampleSize(opts.outWidth,opts.outHeight); opts.inJustDecodeBounds = false;//关闭标记,解析真实的图片
    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts); /**
    * 根据图片的原始宽高比和ImageView的宽高计算图片的采样比例
    * @param outWidth
    * @param outHeight
    * @return
    */
    private int caculateSampleSize(int outWidth, int outHeight) {
    int inSampleSize = 1;
    if(outWidth>outHeight){
    //参考宽进行缩放
    inSampleSize = outWidth/iv_result.getWidth();//1920/300
    }else{
    //参考高进行缩放
    inSampleSize = outHeight/iv_result.getHeight();
    }
    if(inSampleSize<1){
    inSampleSize = 1;
    }
    return inSampleSize;
    }
  • 第三步: 设置图片加载的渲染模式为Config.RGB_565,能降低一半内存:

    opts.inPreferredConfig = Config.RGB_565

5. Volley中的ImageLoader使用以及内存缓存详解

  • 使用ImageLoader加载图片

    protected void loadImage() {
    ImageListener imageListener = ImageLoader.getImageListener(iv_result, R.drawable.ic_launcher, R.drawable.ic_launcher);
    MemoryCache imageCache = new MemoryCache();
    ImageLoader imageLoader = new ImageLoader(queue, imageCache);
    imageLoader.get(imageUrl, imageListener);
    }
    /**
    * 图片内存缓存
    * @author lxj
    *
    */
    public class MemoryCache implements ImageCache{
    private LruCache<String, Bitmap> lruCache;
    //app可用内存的8分之一
    private int maxSize = (int) (Runtime.getRuntime().totalMemory()/8);
    public MemoryCache(){
    lruCache = new LruCache<String, Bitmap>(maxSize){
    @Override
    protected int sizeOf(String key, Bitmap value) {
    return value.getHeight()*value.getRowBytes();
    }
    };
    }
    @Override
    public Bitmap getBitmap(String url) {
    return lruCache.get(url);
    } @Override
    public void putBitmap(String url, Bitmap bitmap) {
    lruCache.put(url, bitmap);
    }
    }
  • 内存缓存详解

    • 内存缓存的存储结构:一般是map,因为需要存取
    • 在Android2.3之前还没有好的内存缓存策略出现,一般采用SoftRefrence对Bitmap进行包装,能尽量保证不会出现oom,几种引用的解释如下:

      • 强引用 : 引用默认就是强引用, 即使内存oom, 也不会去回收对象
      • 软应用:使用SoftRefrence去包装一个对象,内存不足的时候去回收对象,尽量保证不oom,代码如下:

        HashMap<String, SoftReference<Bitmap>> map = new HashMap<String, SoftReference<Bitmap>>();
        SoftReference<Bitmap> reference = map.get(url);
        Bitmap bitmap = reference.get();
      • 弱引用:使用WeakReference保证一个对象,一般不用
    • 在Android2.3之后Google提供了Lru算法的实现类,即LruCache,并推荐我们使用LruCache来实现图片的内存缓存,该类有效解决了Android中图片内存缓存的难题,常见几种内存缓存策略有:
      • Least Frequently Used(LFU): 删除使用频率最少的
      • Least Recently Used(LRU): 删除最近最少使用的
      • First in First out(FIFO): 删除最先添加进来的
      • Most Recently Used(MRU): 删除最近最多使用的
    • LruCache内部实现原理(重点)
      • 内部使用按照访问顺序排序的LinkedHashMap来存储数据
      • 每次缓存命中,该条会按照元素的访问次数进行重新排序
      • 并会判断缓存size是否超出maxSize,如果超出则移除最下方的数据,即最少使用的数据
      • 我们必须实现sizeOf方法,用来指定每条数据的size,此处是返回bitmap的大小
    • 了解XUtil等开源类库对图片内存缓存的实现
    • 了解图片的磁盘缓存的实现DiskLruCache

6. Volley中的NetworlImageView的使用

MemoryCache imageCache  = new MemoryCache();
ImageLoader imageLoader = new ImageLoader(queue, imageCache);
net_imageview.setImageUrl(imageUrl, imageLoader);

7. 自定义Volley的Request

  • 我们在开发中更多的是请求一个url,然后将结果解析为java bean,所以封装一个具有该功能的Request类,GosnRequest
  • 代码如下:

    protected void execGsonRequest() {
    GsonRequest<Stu> gsonRequest = new GsonRequest<Stu>(url, Stu.class, new Listener<Stu>() {
    @Override
    public void onResponse(Stu stu) {
    tv_result.setText(stu.toString());
    }
    }, new MyErrorListener());
    queue.add(gsonRequest);
    }
    public class GsonRequest<T> extends Request<T>{
    private Class<T> clazz;
    private final Listener<T> mListener;
    public GsonRequest(String url,Class<T> clazz,Listener<T> listener, ErrorListener errorListener) {
    super(url, errorListener);
    mListener = listener;
    this.clazz = clazz;
    }
    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
    String parsed;
    try {
    parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
    } catch (UnsupportedEncodingException e) {
    parsed = new String(response.data);
    }
    //解析json,返回response
    T t = new Gson().fromJson(parsed,clazz );
    return Response.success(t, HttpHeaderParser.parseCacheHeaders(response));
    }
    @Override
    protected void deliverResponse(T response) {
    mListener.onResponse(response);
    }
    }

8. 使用Volley取消网络请求

  • 给每个Request添加tag标识

    stringRequest.setTag(this);
  • 调用取消请求的方法

    queue.cancelAll(this);

9. 使用Volley发送post请求,需要自己重写Request的getParams方法

 public class PostReuqest extends StringRequest {
private Map<String, String> params;
public PostReuqest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
super(url, listener, errorListener);
}
public PostReuqest(int method,String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
super(method,url, listener, errorListener);
}
public void setParams(Map<String, String> params){
this.params = params;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
} PostReuqest stringRequest = new PostReuqest(Request.Method.POST,Api.LOGIN, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
text.setText(response);
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) { }
});
HashMap<String,String> map = new HashMap<>();
map.put("username","hehehe");
map.put("password","12321");
stringRequest.setParams(map);

10. 对Volley进行二次封装

/**
* Volley的二次封装类
* @author lxj
*
*/
public class VolleyHelper {
private RequestQueue requestQueue;
MemoryCache imageCache = new MemoryCache();
private static VolleyHelper mInstance = null;
private VolleyHelper(Context context){
requestQueue = Volley.newRequestQueue(context); }
public static VolleyHelper get(Context context){
if(mInstance==null){
mInstance = new VolleyHelper(context);
}
return mInstance;
}
public <T> void executeRequest(Request<T> request){
requestQueue.add(request);
}
/**
* 执行GsonRequest
* @param url
* @param clazz
* @param listener
* @param errorListener
*/
public <T> void executeGsonRequest(String url,Class<T> clazz,Listener<T> listener,ErrorListener errorListener){
GsonRequest<T> gsonRequest = new GsonRequest<T>(url, clazz, listener, errorListener);
gsonRequest.setTag(url);
requestQueue.add(gsonRequest);
}
/**
* 取消请求
* @param tag
*/
public void cancelRequest(String tag){
requestQueue.cancelAll(tag);
}
/**
* 加载图片
* @param imageUrl
* @param imageView
*/
public void loadImage(String imageUrl,ImageView imageView){
ImageListener imageListener = ImageLoader.getImageListener(imageView, R.drawable.ic_launcher, R.drawable.ic_launcher);
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
imageLoader.get(imageUrl, imageListener);
}
}

Volley的初步了解的更多相关文章

  1. Android网络编程系列之Volley总结

    前言 Volley的中文翻译为“齐射.并发”,是在2013年的Google大会上发布的一款Android平台网络通信库,具有网络请求的处理.小图片的异步加载和缓存等功能,能够帮助 Android AP ...

  2. 小记:对Android网络下载工具的初步封装!(包括json,字符串下载(volley),和图片下载(glide))

    import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkIn ...

  3. Android 学习笔记之Volley开源框架解析(二)

    PS:Volley已经学完,可以安心的写一下博客总结一下了... 学习内容: 1.Request的完整封装... 2.RetryPolicy,DefaultRetryPolicy(请求重试策略源码解析 ...

  4. Android网络通信Volley框架源代码浅析(三)

    尊重原创 http://write.blog.csdn.net/postedit/26002961 通过前面浅析(一)和浅析(二)的分析.相信大家对于Volley有了初步的认识,可是假设想更深入的理解 ...

  5. 开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:小杨的博客    http://blog.csdn.net/qq_32059827/article/details/5278849 ...

  6. 一口一口吃掉Volley(二)

    欢迎访问我的个人博客转发请注明出处:http://www.wensibo.top/2017/02/17/一口一口吃掉Volley(二)/ 相信看了第一篇教程之后,你应该会对Volley有一个初步的了解 ...

  7. 移动端之Android开发的几种方式的初步体验

    目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...

  8. CSharpGL(29)初步封装Texture和Framebuffer

    +BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(29)初步封装Texture和Framebuffer +BIT祝威+悄悄在此留下版了个权的信息说: Texture和Framebuffe ...

  9. 快速Android开发系列网络篇之Volley

    Volley是Google推出的一个网络请求库,已经被放到了Android源码中,地址在这里,先看使用方法 RequestQueue mRequestQueue = Volley.newRequest ...

随机推荐

  1. Dropbox电面面经

    他家电面有2轮,等待onsite.. . 电面1: 国人MM面的.这点感觉非常难得. 统计近期5分钟的点击量,实现hit和getHit两个函数.这题是他家高频题,我用deque实现的,hit的均摊时间 ...

  2. 【C/C++学院】0901-设计模式的汇总演练

    备忘录模式 数据库的备份,文档编辑中的撤销等功能 #include <iostream> #include <string> #include <vector> u ...

  3. 《modern operating system》 chapter 6 DEADLOCKS 笔记

    DEADLOCKS Both processes are blocked and will remain so forever. This situation is called a deadlock ...

  4. android 不同进程间的调用 AIDL 实现通讯服务

    android 不同进程间的调用  AIDL 实现通讯服务       近期对aidl android 不同进程间的调用,不同运用间的调用做了一些尝试: 过程例如以下: 1:首先在要被调用的程序里写好 ...

  5. TinyXml 与 Rapidxml效率对照

    曾经在做开发中一直使用TinyXml,在网上搜索说Rapidxml的效率比tinyXml高.个人比較喜欢追求效率.所以忍不住尝试性使用Rapidxml. RapidXml 的官方站点例如以下: htt ...

  6. java重载中的基本类型的自动类型转换

    当传递到函数的参数的数据类型表示的范围小于函数形参的参数类型遵循如下原则 : char类型比较特殊, 直接转换为int:  char ->int ->long->float-> ...

  7. 记一次Tomcat无法正常启动的查错与解决之路

    使用LombozEclipse运行某Web应用,结果总是404. 换另一个Eclipse运行,还是404. 换Tomcat到更高版本,还是404. 直接启动Tomcat,闪退. 用重定向拦截输出,可惜 ...

  8. 【MongoDB】The description of procedure in MongoDB

    In this blog the procedure of mongodb will be described in details. It is known that mongodb has pro ...

  9. JNI/NDK开发指南(2)

    1.生成动态库.so,存放于手机的system/lib/中(APP怎样将.so存入该文件夹,奇怪?????),Java层调用JNI的类会运行静态代码System.loadLibrary("* ...

  10. leetCode 81.Search in Rotated Sorted Array II (旋转数组的搜索II) 解题思路和方法

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...