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