队列详解与封装
最后更新于:2022-04-01 23:20:17
# 目录
[TOC]
# 队列的创建
```java
// 默认并发值为3
RequestQueue reqQueue = NoHttp.newRequestQueue();
// 或者传入并发值
RequestQueue reqQueue = NoHttp.newRequestQueue(1);
```
> 并发的意思是,最多可以同时并行多少个请求。
1. 当一个页面初始化时要请求多个接口,那么耗时相对会更长,对于用户的体验是很差的,所以如果能同时执行多个请求,那么将会缩短网络请求的时间。
2. 假如我们传入的并发值是3,但是我们同时添加了5个请求到队列,第四个请求将会在前三个请求的任何一个完成后被发起,以此类推...
3. 假如我们想让请求一个个执行,那么我们讲队列设置为1个并发,我们连续添加了10个请求到队列,这个10个队列将会按照添加顺序依次执行。如果要设置请求优先级,请往下看。
4. 如果给`Request`设置了优先级,将优先执行优先级别较高的请求,关于优先级别[请看这里](http://doc.nohttp.net/222885)。
# 队列的封装
创建一个队列应该多次使用,因为每创建一个队列,就会创建指定`并发值`个线程,如果创建太多队列就会耗资源,所以我们要把队列封装成单例模式。
## 队列的单例模式封装
```java
public class CallServer {
private static CallServer instance;
/**
* 请求队列。
*/
private RequestQueue requestQueue;
private CallServer() {
requestQueue = NoHttp.newRequestQueue(3);
}
/**
* 请求队列。
*/
public static CallServer getInstance() {
if (instance == null)
synchronized (CallServer.class) {
if (instance == null)
instance = new CallServer();
}
return instance;
}
/**
* 添加一个请求到请求队列。
*
* @param what 用来标志请求, 当多个请求使用同一个Listener时, 在回调方法中会返回这个what。
* @param request 请求对象。
* @param listener 结果回调对象。
*/
public void add(int what, Request request, OnResponseListener listener) {
requestQueue.add(what, request, listener);
}
/**
* 取消这个sign标记的所有请求。
* @param sign 请求的取消标志。
*/
public void cancelBySign(Object sign) {
requestQueue.cancelBySign(sign);
}
/**
* 取消队列中所有请求。
*/
public void cancelAll() {
requestQueue.cancelAll();
}
}
```
* 封装如何使用
我们只需要在需要使用请求的地方这样调用即可:
```java
Request request = ...
...
CallServer.getInstance().add(0, request, Listener);
```
## 在BaseActivity和BaseFragment中封装
如果你看[这篇文章](http://doc.nohttp.net/222886),你会发现取消请求虽然可以与`Activity`、`Fragment`的生命周期绑定,但是每个Activity和Fragment都这么写就显得有点麻烦了,所以我们这里把这些操作写在`BaseActivity`、`BaseFragment`中。
在Base中提供一个请求的方法,具体参数请结合自己的业务和习惯封装。
```java
...
private Object cancelObject = new Object();
public void request(int what, Request request, OnResponseListener listener) {
// 这里设置一个sign给这个请求。
request.setCancelSign(cancelObject);
CallServer.getInstance().add(what, request, listener);
}
@Override
protected void onDestroy() {
// 在组件销毁的时候调用队列的按照sign取消的方法即可取消。
CallServer.getInstance().cancelBySign(cancelObject);
super.onDestroy();
}
```
**推荐阅读**
[1. NoHttp的队列异步请求](http://doc.nohttp.net/222880)
[2. 取消请求、取消队列中的请求](http://doc.nohttp.net/222886)
[3. Request优先级别](http://doc.nohttp.net/222885)
';