• Android网络编程系列之Volley总结


    前言

    Volley的中文翻译为“齐射、并发”,是在2013年的Google大会上发布的一款Android平台网络通信库,具有网络请求的处理、小图片的异步加载和缓存等功能,能够帮助 Android APP 更方便地执行网络操作,而且更快速高效。在Google IO的演讲上,其配图是一幅发射火弓箭的图,有点类似流星。这表示,Volley特别适合数据量不大但是通信频繁的场景

    1.Volley特点

    • 适用于频繁请求而每次请求数据量不会很大;
    • 在请求的基础上做了磁盘缓存;
    • 防止多次相同请求浪费资源;
    • 提供String、Json、图片异步下载;
    • 网络请求的优先级处理;
    • 图片请求无需担心生命周期问题。
    • 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)

    2.Volley的使用

    (1)新建一个RequestQueue

    RequestQueue mQueue = Volley.newRequestQueue(context); 
    

    (2)创建一个StringRequest实例(Volley提供,StringRequest、ImageRequest、JsonRequest)

    StringRequest stringRequest = new StringRequest("http://www.baidu.com",  
    	new Response.Listener<String>() {  
    		@Override  
    		public void onResponse(String response) {  
    			Log.d("TAG", response);  
    		}  
    	}, new Response.ErrorListener() {  
    		@Override  
    		public void onErrorResponse(VolleyError error) {  
    			Log.e("TAG", error.getMessage(), error);  
    		}  
    	});

    我们可以设置请求的方式

    StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener); 
    

    同样可以设置提交的参数

    StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {  
        @Override  
        protected Map<String, String> getParams() throws AuthFailureError {  
            Map<String, String> map = new HashMap<String, String>();  
            map.put("params1", "value1");  
            map.put("params2", "value2");  
            return map;  
        }  
    };

    (3)将XXXRequest对象添加进队列中

    mQueue.add(stringRequest); 
    

    (4)调用RequestQueue的start方法就可以开始一条网络请求

    mQueue.start();
    

    3.Volley例子

    (1)StringRequest请求

    GET请求

    //1.创建出请求队列
    RequestQueue mRequestQueue = Volley.newRequestQueue(this);
    //2.创建出来字符串请求对象: StringRequest
        /**
        * 1param: 请求方式 get/post(get方法默认省略)
        * 2p:请求的url地址
        * 3p:请求成功后的接口回调
        * 4p:请求失败后回调
        * 5p:成功的监听,通过参数返回请求到的数据
        * 6p:失败的监听,失败在这里处理
        */
        StringRequest mStrReq = new StringRequest(Request.Method.GET, "https://www.baidu.com",
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    // 这个方法运行在主线程中,可以直接更新ui
                    // 通过参数返回请求到的数据
                    mTv_result.setText(response);
                    Toast.makeText(StrReqActivity.this, "下载成功", Toast.LENGTH_SHORT).show();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // 这个方法运行在主线程中,可以直接更新ui
                    // 失败在这里处理
                    Toast.makeText(StrReqActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
                }
            });
            //设置Tag值
            mStrReq.setTag("100");
            btn_req.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //3.把请求对象添加到请求队列中,会自动发出请求
                    mRequestQueue.add(mStrReq);
                }
            });
    

    POST请求

    String url_post = "http://zhushou.72g.com/app/gift/gift_list/";
    StringRequest mStrReq = new StringRequest(Request.Method.POST, url_post
        , new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                //
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //
            }
        }) {//这里需要重写getParams方法 
           @Override
           protected Map<String, String> getParams() throws AuthFailureError {
               //把post的请求参数,放入请求体中
               //请求条件:platform=2&gifttype=1&compare=60841c5b7c69a1bbb3f06536ed685a48
               Map<String, String> params = new HashMap<>();
               params.put("platform", "2");
               params.put("gifttype", "1");
               params.put("compare", "60841c5b7c69a1bbb3f06536ed685a48");
               return params;
            }
        };
        //点击加入到请求队列中
        btn_req_json.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mRequestQueue.add(mStrReq);
            }
       });
    

    Volley支持手动/自动取消请求,可以在Activity销毁的时候手动取消请求:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消请求:有三种方式
        //1. 取消对应的请求对象
        mStrReq.cancel();
        //2. 取消请求队列中对应tag的请求
        //mRequestQueue.cancelAll("100");
        //3. 取消请求队列中所有的请求
        //mRequestQueue.cancelAll(this);
    }

    (2)JsonObjectRequest与JsonArrayRequest(json数据请求)

    JsonObjectRequest请求(一样要加到请求队列中才会自动加载)返回的是一个JSONObject对象,创建方法如下:

    JsonObjectRequest jsonObjectRequest =new JsonObjectRequest(Request.Method.GET, url, 
        new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) {          // } },
        new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {          // } });

    (3)ImageRequest图片请求

    //1.首先有请求队列
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    //2.请求对象
    //1p 图片下载的url
    //2p 下载成功后,返回一个bitmap对象
    //3p4p 最大宽度和最大高度,如果超过最大宽度和高度,会进行压缩到你设置的宽度和高度,0不限制
    //5p 图片加载的形式
    //6p图片显示的质量:RGB_565: 每个像素2字节   ARGB_8888:每个像素占4个字节
    //7p下载图片失败后,在这里边处理
    ImageRequest imgRequest = new ImageRequest(url_img, new Response.Listener<Bitmap>() {
                @Override
                public void onResponse(Bitmap response) {
                    //显示成功的图片
                    iv_show.setImageBitmap(response);
                }
            }, 0, 0, ImageView.ScaleType.FIT_XY, Bitmap.Config.RGB_565, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    //设置失败的图片
                    iv_show.setBackgroundResource(R.mipmap.ic_launcher);
                }
            });
    

    (4)Volley的初步封装

    package com.alex.week06_02.utils;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.widget.ImageView;
    import com.alex.week06_02.BitmapCache;
    import com.android.volley.AuthFailureError;
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.toolbox.ImageLoader;
    import com.android.volley.toolbox.ImageRequest;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;
    import java.util.Map;
    
    /**
     * 單例模式對Volley進行簡單封裝
     * @author noonecode
     */
    public class VolleyUtils {
    
        private static VolleyUtils mInstance;
        private RequestQueue mRequestQueue;
        private ImageLoader mImageLoader;
        private ImageLoader.ImageCache mCache;
    
        private VolleyUtils(Context context) {
            mRequestQueue = Volley.newRequestQueue(context);
            mCache = new BitmapCache();
            mImageLoader = new ImageLoader(mRequestQueue, mCache);
        }
        //單例模式
        public VolleyUtils newInstance(Context context) {
            if (mInstance == null) {
                synchronized (VolleyUtils.class) {
                    if (mInstance == null) {
                        mInstance = new VolleyUtils(context);
                    }
                }
            }
            return mInstance;
        }
    
        public RequestQueue getRequestQueue() {
            return mRequestQueue;
        }
    
        public ImageLoader getImageLoader(){
            return mImageLoader;
        }
    
        /**
         * 发送一个字符串请求
         * @param method 请求方式GET/POST
         * @param url 请求的链接
         * @param params POST请求时的参数,可为null
         * @param listener 请求返回数据的监听器
         * @param errorListener 请求发生错误的监听器
         */
        public void sendStringRequest(final int method, String url, final Map<String, String> params, Response.Listener<String> listener,
                                      Response.ErrorListener errorListener){
            StringRequest stringRequest = new StringRequest(method, url, listener, errorListener){
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    if (method == Method.POST) {
                        return params;
                    }
                    return null;
                }
            };
            mRequestQueue.add(stringRequest);
        }
    
        /**
         * 发送一个字符串请求
         * @param url 图片的链接
         * @param listener 成功获取到Bitmap的监听器
         * @param maxWidth 最大宽度,0则不限制
         * @param maxHeight 最大高度,0则不限制
         * @param scaleType ImageView的拉伸属性
         * @param decodeConfig 图片的格式
         * @param errorListener 失败的监听器
         */
        public void sendImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
                                     ImageView.ScaleType scaleType, Bitmap.Config decodeConfig, Response.ErrorListener errorListener){
            ImageRequest imageRequest = new ImageRequest(url, listener, maxWidth, maxHeight, scaleType, decodeConfig, errorListener);
            mRequestQueue.add(imageRequest);
        }
    }
    

    使用方法: 
    通过单例的方法获得VolleyUtils的对象

    private VolleyUtils mVolleyUtils;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //~~~
        mVolleyUtils = VolleyUtils.newInstance(this);
    }
    

    发出一个字符串的请求:

    mVolleyUtils.sendStringRequest(Request.Method.GET, "https://www.baidu.com", null, new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            tvShow.setText(response);
                        }
                    }, null);
    

    发出一个图片的请求:

    mVolleyUtils.sendImageRequest("https://www.baidu.com/img/bd_logo1.png", new Response.Listener<Bitmap>() {
                        @Override
                        public void onResponse(Bitmap response) {
                            iv_show.setImageBitmap(response);
                        }
                    }, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.RGB_565, null);
    

    4.Volley缺点

    • 它只适用于频繁而数据量小的请求。(当请求的是比较大的数据时,这个Volley框架发挥的作用就不是很大了。)
    • 它只实现了一级缓存(磁盘缓存)。(这样做虽然节省内存资源的消耗,但是读写数据的速度会比较慢。我们可以在这个基础上进行优化,多加一级内存缓存,实现多级缓存。读者可以自行对这个框架进行优化。对于缓存机制,个人觉得可以学习下Universal image loader这个框架,里面有几种缓存机制写得很好

    好了,以上是对Volley框架的学习和理解。

    参考链接:

    https://blog.csdn.net/itachi85/article/details/51043704

    https://www.cnblogs.com/caichongyang/articles/4399790.html

    https://blog.csdn.net/ljx19900116/article/details/42272003

    https://blog.csdn.net/qq_32001935/article/details/78224149

    https://blog.csdn.net/qq_33425116/article/details/52685053

     

  • 相关阅读:
    C# 微信品牌会员卡开发(微信会员卡2.0)
    管理者问卷调查
    二:elementui源码解析之改造demoblock可以直接在卡片里编辑修改代码并生效渲染到界面上
    MySql 的@符号定义一个变量在sql里的占位符作用
    swift 代码段的重构
    k8skubeadm高可用安装部署
    LeetCode> 71. 简化路径
    Linux进程管理
    Linux中断下半部及推后执行的工作
    Linux进程调度
  • 原文地址:https://www.cnblogs.com/Daniel-android/p/9687324.html
Copyright © 2020-2023  润新知