队列详解与封装

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

队列的单例模式封装

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优先级别

文章导航