队列详解与封装

目录

队列的创建

// 默认并发值为3
RequestQueue reqQueue = NoHttp.newRequestQueue();

// 或者传入并发值
RequestQueue reqQueue = NoHttp.newRequestQueue(1);

并发的意思是,最多可以同时并行多少个请求。

  1. 当一个页面初始化时要请求多个接口,那么耗时相对会更长,对于用户的体验是很差的,所以如果能同时执行多个请求,那么将会缩短网络请求的时间。

  2. 假如我们传入的并发值是3,但是我们同时添加了5个请求到队列,第四个请求将会在前三个请求的任何一个完成后被发起,以此类推...

  3. 假如我们想让请求一个个执行,那么我们讲队列设置为1个并发,我们连续添加了10个请求到队列,这个10个队列将会按照添加顺序依次执行。如果要设置请求优先级,请往下看。

  4. 如果给Request设置了优先级,将优先执行优先级别较高的请求,关于优先级别请看这里

队列的封装

创建一个队列应该多次使用,因为每创建一个队列,就会创建指定并发值个线程,如果创建太多队列就会耗资源,所以我们要把队列封装成单例模式。

队列的单例模式封装

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 <T> void add(int what, Request<T> request, OnResponseListener listener) {
        requestQueue.add(what, request, listener);
    }

    /**
     * 取消这个sign标记的所有请求。
     * @param sign 请求的取消标志。
     */
    public void cancelBySign(Object sign) {
        requestQueue.cancelBySign(sign);
    }

    /**
     * 取消队列中所有请求。
     */
    public void cancelAll() {
        requestQueue.cancelAll();
    }
}
  • 封装如何使用
    我们只需要在需要使用请求的地方这样调用即可:
    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 <T> void request(int what, Request<T> request, OnResponseListener<T> listener) {
    // 这里设置一个sign给这个请求。
    request.setCancelSign(cancelObject);
        
    CallServer.getInstance().add(what, request, listener);
}

@Override
protected void onDestroy() {
    // 在组件销毁的时候调用队列的按照sign取消的方法即可取消。
    CallServer.getInstance().cancelBySign(cancelObject);
    super.onDestroy();
}

推荐阅读
1. NoHttp的队列异步请求
2. 取消请求、取消队列中的请求
3. Request优先级别

文章导航