Volley - 串行请求而不是并行?

Volley - serial requests instead of parallel?

我正在使用 volley 从我的 Android 应用程序发出 HTTP 请求。 这是我正在使用的代码:

public class RequestPool {


    private static RequestPool mInstance;

    private RequestQueue mRequestQueue;

    private static Context mContext;

    private RequestPool(Context context) {

        mContext = context;
        mRequestQueue = getRequestQueue();


    }

    public static synchronized RequestPool getInstance(Context context) {

        if (mInstance == null) {
            mInstance = new RequestPool(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {

        getRequestQueue().add(req);
    }
}

我想将请求添加到队列但控制它们的执行方式,例如:

在任意时间将多个请求添加到池中,池将仅执行第一个请求(队列的头部),然后在完成时执行下一个......等等......

也许有办法让同时 执行串行和并行请求?

可能吗?

谢谢。

如果您想 运行 并行请求,那么您只需不断向队列中添加请求。请求默认是异步的。

如果你想运行串行请求,那么有两种方法。

一个是在第一个请求的onResponse里面添加第二个请求。这基本上会链接多个异步请求。

二是使用阻塞的RequestFuture。例如,执行此方法将阻塞,直到获得响应。

private String blockingRequest(String url) {

    RequestFuture<String> future = RequestFuture.newFuture();

    StringRequest sr = new StringRequest(url, future, future);
    queue.add(sr);
    String response = null;

    try {
        response =  future.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return response;
}

基本上你可以像这样堆叠多个阻塞请求方法:

String response1 = blockingRequest1(url1);
// other methods
String response2 = blockingRequest2(url2);

blockingRequest2 将在 blockingRequest1 完成后执行。如果没有 Future,两种方法将同时执行。不用说,您将需要 运行 在 UI 线程中 而不是 阻塞方法(例如 Thread、AsyncTask 和个人最喜欢的 RxJava Observable)。

这可以通过创建线程池为 1 的请求来完成。

int MAX_SERIAL_THREAD_POOL_SIZE = 1;
final int MAX_CACHE_SIZE = 2 * 1024 * 1024; //2 MB

private static RequestQueue prepareSerialRequestQueue(Context context) {
    Cache cache = new DiskBasedCache(context.getCacheDir(), MAX_CACHE_SIZE);
    Network network = getNetwork();
    return new RequestQueue(cache, network, MAX_SERIAL_THREAD_POOL_SIZE);
}

在 getNetwork() 方法中

private static Network getNetwork() {
    HttpStack stack;
    if(Build.VERSION.SDK_INT >= 9) {
        stack = new HurlStack();
    } else {
        String userAgent = "volley/0";
        stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    }
    return new BasicNetwork(stack);
}

然后我们使用启动方法来启动() 请求队列。

RequestQueue serialRequestQueue = prepareSerialRequestQueue(context);
serialRequestQueue.start();

现在将请求添加到此队列而不是截击请求队列。例如:

StringRequest requestOne = new StringRequest(Request.Method.GET, "http://www.example1.com", this, this);
StringRequest requestTwo = new StringRequest(Request.Method.GET, "http://www.example2.com", this, this);
StringRequest requestThree = new StringRequest(Request.Method.GET, "http://www.example3.com", this, this);
serialRequestQueue.add(requestTwo);
serialRequestQueue.add(requestOne);
serialRequestQueue.add(requestThree);

在这种情况下,将首先处理结果 requestTwo,然后分别处理 requestOnerequestThree。如果您不想阻止请求处理并让它们连续发生,这会有所帮助。

这是我正在使用的:

private static RequestQueue newRequestQueue(Context context) {
    File cacheFile = new File(context.getCacheDir(), "volley");
    Cache cache = new DiskBasedCache(cacheFile);
    RequestQueue queue = new RequestQueue(cache, new BasicNetwork(new HurlStack()), 1);
    queue.start();
    return queue;
}