【问题标题】:Volley - serial requests instead of parallel?Volley - 串行请求而不是并行?
【发布时间】:2015-05-10 08:48:05
【问题描述】:

我正在使用 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);
    }
}

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

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

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

有可能吗?

谢谢。

【问题讨论】:

    标签: android android-volley


    【解决方案1】:

    这可以通过创建一个线程池为 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);
    }
    

    还有我们 start() 请求队列的 start 方法。

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

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

    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。如果您不想阻止请求处理并让它们连续发生,这会有所帮助。

    【讨论】:

    • 你可以得到要点here
    • 你能帮帮我吗?我的问题是如何处理所有 3 个请求的响应
    • 在创建请求时,函数中有参数,您可以在其中提供参数。 Response.Listener 参数将帮助您做到这一点。你可以看看here,看看StringRequest是如何创建的,你会得到答案的。
    【解决方案2】:

    如果您想运行并行请求,那么您只需将请求添加到队列中即可。请求默认是异步的。

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

    一个是在第一个请求的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)中运行阻塞方法not

    【讨论】:

    • 感谢您的快速回复。其实我已经在使用第一种方法了。问题是有多个线程将请求添加到请求池中。所以我可能会使用你提到的两种方法..有机会使用'blockingRequest'吗?
    • 故事不多,但我编辑了我的答案来说明它。 RequestQueue 顾名思义,仅按先服务 (FIFO) 顺序排列请求。它已经同步,因此您无需担心从多个线程访问它。
    • 它们是并行的,但我会指出,同时执行的请求的数量由默认为 4 的线程池大小控制(RequestQueue 中的 DEFAULT_NETWORK_THREAD_POOL_SIZE)
    【解决方案3】:

    这是我正在使用的:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-18
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多