Android热门网络框架Volley详解
Volley简介
volley的英文意思是‘群发’、‘迸发’。Volley是2013年谷歌官方发布的一款Android平台上的网络通信库。Volley非常适合一些数据量不大,但需要频繁通信的网络操作。使用Volley进行网络开发可以使我们的开发效率得到很大的提升,而且性能稳定性也很高。但是Volley不适合用于文件的上传下载操作。
Volley的特点
- 使网络通信更快,更简单,更健壮;
- Get/Post网络请求及网络图像的高效率异步请求;
- 可以对网络请求的优先级进行排序处理;
- 可以进行网络请求的缓存;
- 可以取消请求;
Volley默认配置请求实现
google地址:https://developer.android.google.cn/training/volley
1.导包
dependencies {
...
implementation 'com.android.volley:volley:+'
}
2.AndroidManifest网络权限配置
<!-- 添加网络操作权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
3.实际使用
public void request() {
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://v.juhe.cn/joke/content/list.php?sort=desc&page=&pagesize=&time=1552055993&key=5df04feb8b3fc0bf91947a5ca91916c0";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
int end = response.length() > 500 ? 500 : response.length();
tvRequest.setText("Response is: " + response.substring(0, end));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
tvRequest.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
上面实现的是GET请求,那么POST请求的参数要怎么提供?
很简单,重写getParams()函数。实际上getParams()函数在Request类里,Request是一个抽象类,他有3个子类StringRequest、JsonObjectRequest和JsonArrayRequest。区别就在于请求数据的返回类型不一样。
public void request() {
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://v.juhe.cn/joke/content/list.php";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
int end = response.length() > 500 ? 500 : response.length();
tvRequest.setText("Response is: " + response.substring(0, end));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
tvRequest.setText("That didn't work!");
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map=new HashMap<>();
map.put("sort","desc");
map.put("time","1552055993");
map.put("key","5df04feb8b3fc0bf91947a5ca91916c0");
return map;
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
把原先在url里参数添加到了Map里,通过getParams函数提供。
最基本的Volley网络请求就完成了
Volley使用进阶
1.Volley与Activity生命周期的联动
简单来说就是Volley中的请求需要与Activity的生命周期进行关联。在Android销毁时关闭未完成的请求,防止请求在后台运行造成内存溢出等情况发生。
那么如何进行关联?
设置Tag标签,因为取消请求需要在请求队列中通过Tag标签进行查找
request.setTag("TAG")
...
@Override
protected void onStop () {
super.onStop();
if (requestQueue != null) {
requestQueue.cancelAll(TAG);
}
}
2.不使用默认配置,给请求队列设置缓存
RequestQueue 可以通过 Volley.newRequestQueue(context)获取一个默认的配置
同时也支持手段配置缓存
RequestQueue requestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
requestQueue = new RequestQueue(cache, network);
// Start the queue
requestQueue.start();
3.自定义请求的返回类型
在大多数的情况下我们都需要返回的是一个可以直接使用的bean对象,这时就需要自定义一个返回对象,比如GsonRequest
下面的代码是官网给出的示例,我们只需要注意两个地方deliverResponse(T response)和parseNetworkResponse(NetworkResponse response),这两个函数都是自定义需要实现的方法。
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
deliverResponse(T response)函数的注释说它的功能就是传递解析之后的对象。所以我们只需要把response传递给解析成功的回调函数
@Override
protected void deliverResponse(T response) {
succeedListener.onResponse(response);
}
parseNetworkResponse(NetworkResponse response)函数的作用就是转化。