前言

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

Android网络编程系列之Volley总结的更多相关文章

  1. Android网络编程系列 一 TCP/IP协议族

    在学习和使用Android网路编程时,我们接触的仅仅是上层协议和接口如Apache的httpclient或者Android自带的httpURlconnection等等.对于这些接口的底层实现我们也有必 ...

  2. Android网络编程系列 一 Socket抽象层

     在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽 ...

  3. Android网络编程系列 一 TCP/IP协议族之传输层

    这篇借鉴的文章主要是用于后续文章知识点的扩散,在此特作备份和扩散学习交流. 传输层中有TCP协议与UDP协议. 1.UDP介绍 UDP是传输层协议,和TCP协议处于一个分层中,但是与TCP协议不同,U ...

  4. Android网络编程系列 一 JavaSecurity之JSSE(SSL/TLS)

    摘要:     Java Security在Java存在已久了而且它是一个非常重要且独立的版块,包含了很多的知识点,常见的有MD5,DigitalSignature等,而Android在Java Se ...

  5. Android网络编程系列 一 TCP/IP协议族之链路层

    这篇借鉴的文章主要是用于后续文章知识点的扩散,在此特作备份和扩散学习交流. 数据链路层有三个目的: 为IP模块发送和 接收IP数据报. 为ARP模块发送ARP请求和接收ARP应答. 为RARP发送RA ...

  6. Android网络编程系列 一 TCP/IP协议族之网际层

    这篇借鉴的文章主要是用于后续文章知识点的扩散,在此特作备份和扩散学习交流. 网际层包括:IP.ICMP.IGMP 以及处在网际层实际工作在链路层的 ARP 和 RARP等等协议. 1.IP协议 互联网 ...

  7. Android网络编程系列之HTTP协议原理总结

    前言 作为搞移动开发的我们,免不了与网络交互打交道.虽然市面上很多开源库都封装的比较到位,我们实现网络访问也轻车熟路.但还是十分有必要简要了解一下其中的原理,以便做到得心应手,也是通往高级开发工程师甚 ...

  8. Android网络编程(三)Volley使用方法全解析

    相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection 前言 Volley想必许多人都用过,为了建立网络编程的知识 ...

  9. Android网络编程(一)HTTP协议原理

    相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection Android网络编程(三)Volley使用方法全解析 A ...

随机推荐

  1. Scala使用隐式转换进行比较

    Boy.scala class Boy(val name: String, val faceValue: Int) extends Comparable[Boy]{ override def comp ...

  2. JDK提供的四种线程池代码详解

    一.线程池什么时候使用,会给我们带来什么好处? 如果很多用户去访问服务器,用户访问服务器的时间是非常短暂的,那么有可能在创建线程和销毁线程上花费的时间会远远大于访问所消耗的时间,如果采用线程池会使线程 ...

  3. JavaScript概念之screen/client/offset/scroll/inner/avail的width/left 分类: JavaScript HTML+CSS 2015-05-27 16:42 635人阅读 评论(0) 收藏

    原文地址:http://caibaojian.com/js-name.html JS中获取各种宽度和距离,常常让我们混淆,各种浏览器的不兼容让我们很头疼,现在就在说说js中有哪些宽度和距离. 1.名词 ...

  4. 数据库设计 Step by Step (1)——扬帆启航

    引言:一直在从事数据库开发和设计工作,也看了一些书籍,算是略有心得.很久之前就想针 对关系数据库设计进行整理.总结,但因为种种原因迟迟没有动手,主要还是惰性使然.今天也算是痛下决心开始这项卓绝又令我兴 ...

  5. Centos iptables防火墙关闭启动详解

    CentOS .0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 .直接关闭防火墙 systemctl stop firewalld.service #停止firewal ...

  6. 使用Hexo & Github,搭建属于自己的博客

    经过在网上各种找资料,踩过各种坑,终于搭建好了hexo,直接与gitbub一起使用,搭建起自己的免费的博客. 关于Hexo Hexo是一款基于Node.js的静态博客框架. Hexo特性 风一般的速度 ...

  7. vim 常用命令(一)特殊删除

    dd 可以删除光标当前行: ndd  n代表行数,3dd,删除从当前光标往下3行: di 删除在指定符号内的内容,如 空号,引号内: dt 删除当前光标到指定符号的内容

  8. Yarn和Mesos:资源管理调度平台

    目前得分布式系统中,对于资源管理都采用动态资源划分来取代静态资源划分.它有如下好处: 集群资源利用率高 增加数据共享能力,可以多种计算框架公用一份分布式存储数据. 资源管理抽象模型 概念模型 常见得资 ...

  9. [转]论magento1和magento2的速度性能优化问题

    本文转自:http://www.360magento.com/blog/magento-speed-up/ magento从2007年发展至今,也经历了十余年的磨练,如今也迎来了magento的换代产 ...

  10. 使用WPF教你一步一步实现连连看(三)

    这次首先对以前的结构进行了调整: 第一步:把MyButton按钮的属性独立成一个类,放在一个单独的MyButton.cs中,把图片的初始化也放到里面. 调整代码如下: public class MyB ...