这些天我正在学习如何使用Google排球。这对于快速联网非常方便。似乎所有请求都在Volley的后台运行。例如:
volleyRequestQueue.add(new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, new SignUpResponseListener(), new MyErrorListener()));
使用上面的代码,我们可以进行后台运行的POST调用(非阻塞方式)。现在我的问题是: 是否可以以阻止方式进行POST呼叫?为什么我需要一种阻止方式来进行REST调用?因为有些电话,比如登录,应该在做其他事情之前完成。
由于
答案 0 :(得分:29)
Volley通过RequestFutures支持阻止请求。您创建了一个普通请求,但将其回调设置为您的未来请求,这只是标准Java期货的凌空扩展。对future.get()的调用将阻止。
它看起来像这样
RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, future, future)
volleyRequestQueue.add(request);
try {
JSONObject response = future.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
答案 1 :(得分:1)
我想在加布里埃尔的回答中添加一些东西。虽然RequestFuture
阻塞了调用它的线程并且它符合您的目的,但网络请求本身并不在该线程中执行。相反,它是在后台线程上执行的。
根据我在浏览图书馆时的理解,RequestQueue
中的请求会以start()
方式发送:
public void start() {
....
mCacheDispatcher = new CacheDispatcher(...);
mCacheDispatcher.start();
....
NetworkDispatcher networkDispatcher = new NetworkDispatcher(...);
networkDispatcher.start();
....
}
现在,CacheDispatcher
和NetworkDispatcher
类都扩展了线程。因此,有效地生成了一个新的工作线程,用于使请求队列出列,并将响应返回给RequestFuture
内部实现的成功和错误侦听器。
所以我认为制作一个单独的阻塞线程来使用RequestFuture
没有意义。正如Makibo在他的回答中提到的那样 - &#34;使用回调侦听器onSuccess(在这种情况下为SignUpResponseListener)并将代码放在那里。&#34;
答案 2 :(得分:0)
如果你想在Volley请求之后做一些事情,请在onSuccess上使用回调监听器(在这种情况下使用SignUpResponseListener)并将代码放在那里。这是最好的做法。
答案 3 :(得分:0)
我无法使RequestFuture工作,所以我只使用了像Makibo建议的回调监听器。我不知道他为什么会被投票,这可能是针对不同Volley请求的原始常见问题的最佳解决方案,这些问题都取决于初始登录或其他内容。在此示例中,我想上传照片,但首先我要检查用户是否已登录。如果没有,我会在上传照片之前登录然后等待成功。如果已经登录,请直接上传照片。
这是我的示例代码:
// interface we'll use for listener
public interface OnLoginListener {
public void onLogin();
}
public void uploadPhoto(final String username, final String password, final String photo_location) {
// first setup callback listener that will be called if/when user is logged in
OnLoginListener onLoginListener=new OnLoginListener() {
@Override
public void onLogin() {
uploadPhotoLoggedIn(photo_location);
}
};
// simplistic already logged in check for this example, just checking if username is null
if (loggedInUsername==null) {
// if it null, login and pass listener
httpLogin(username, password, onLoginListener);
} else {
// if not null, already logged in so just call listener method
onLoginListener.onLogin();
}
}
public void httpLogin(String username, String password, final OnLoginListener onLoginListener) {
StringRequest loginRequest = new StringRequest(Request.Method.POST, "https://www.example.com/login.php", new Response.Listener<String>() {
@Override
public void onResponse(String txtResponse) {
Log.d("STACKOVERFLOW",txtResponse);
// call method of listener after login is successful. so uploadPhotoLoggedIn will be called now
onLoginListener.onLogin();
} },
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
Log.d("VOLLEYERROR","error => "+error.toString());
}
}
) {
};
// Just getting the Volley request queue from my application class (GetApplicatio.java), and adding request
GetApplication.getRequestQueue().add(loginRequest);
}