我可以用凌空抽射做同步请求吗?
2022-08-31 08:03:01
想象一下,我所在的服务已经具有后台线程。我能否在同一线程中使用 volley 执行请求,以便同步进行回调?
这有两个原因:
- 首先,我不需要另一个线程,创建它是一种浪费。
- 其次,如果我在ServiceIntent中,线程的执行将在回调之前完成,因此我将没有来自Volley的响应。我知道我可以创建自己的服务,该服务具有一些线程,其中包含我可以控制的运行环,但是在齐射中使用此功能是可取的。
想象一下,我所在的服务已经具有后台线程。我能否在同一线程中使用 volley 执行请求,以便同步进行回调?
这有两个原因:
看起来在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
}
注意@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;
}