我可以用凌空抽射做同步请求吗?

2022-08-31 08:03:01

想象一下,我所在的服务已经具有后台线程。我能否在同一线程中使用 volley 执行请求,以便同步进行回调?

这有两个原因:

  • 首先,我不需要另一个线程,创建它是一种浪费。
  • 其次,如果我在ServiceIntent中,线程的执行将在回调之前完成,因此我将没有来自Volley的响应。我知道我可以创建自己的服务,该服务具有一些线程,其中包含我可以控制的运行环,但是在齐射中使用此功能是可取的。

答案 1

看起来在Volley的类中是可能的。例如,要创建同步 JSON HTTP GET 请求,可以执行以下操作:RequestFuture

RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(URL, new JSONObject(), future, future);
requestQueue.add(request);

try {
  JSONObject response = future.get(); // this will block
} catch (InterruptedException e) {
  // exception handling
} catch (ExecutionException e) {
  // exception handling
}

答案 2

注意@Matthews答案是正确的,但是如果你在另一个线程上,并且在你没有互联网的情况下执行凌空调用,你的错误回调将在主线程上调用,但你所在的线程将永远被阻止(因此,如果该线程是一个 IntentService,你将永远无法向它发送另一条消息,你的服务基本上将失效)。

使用具有超时的版本并捕获错误以退出线程。get()future.get(30, TimeUnit.SECONDS)

要匹配@Mathews答案:

        try {
            return future.get(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            // exception handling
        } catch (ExecutionException e) {
            // exception handling
        } catch (TimeoutException e) {
            // exception handling
        }

下面我将其包装在一个方法中并使用不同的请求:

   /**
     * Runs a blocking Volley request
     *
     * @param method        get/put/post etc
     * @param url           endpoint
     * @param errorListener handles errors
     * @return the input stream result or exception: NOTE returns null once the onErrorResponse listener has been called
     */
    public InputStream runInputStreamRequest(int method, String url, Response.ErrorListener errorListener) {
        RequestFuture<InputStream> future = RequestFuture.newFuture();
        InputStreamRequest request = new InputStreamRequest(method, url, future, errorListener);
        getQueue().add(request);
        try {
            return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Log.e("Retrieve cards api call interrupted.", e);
            errorListener.onErrorResponse(new VolleyError(e));
        } catch (ExecutionException e) {
            Log.e("Retrieve cards api call failed.", e);
            errorListener.onErrorResponse(new VolleyError(e));
        } catch (TimeoutException e) {
            Log.e("Retrieve cards api call timed out.", e);
            errorListener.onErrorResponse(new VolleyError(e));
        }
        return null;
    }

推荐