排球 - 阻止方式的http请求

时间:2013-07-12 06:28:19

标签: android http post android-volley

这些天我正在学习如何使用Google排球。这对于快速联网非常方便。似乎所有请求都在Volley的后台运行。例如:

volleyRequestQueue.add(new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, new SignUpResponseListener(), new MyErrorListener()));

使用上面的代码,我们可以进行后台运行的POST调用(非阻塞方式)。现在我的问题是: 是否可以以阻止方式进行POST呼叫?为什么我需要一种阻止方式来进行REST调用?因为有些电话,比如登录,应该在做其他事情之前完成。

由于

4 个答案:

答案 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();
        ....
    }

现在,CacheDispatcherNetworkDispatcher类都扩展了线程。因此,有效地生成了一个新的工作线程,用于使请求队列出列,并将响应返回给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);
}