Android - Volley RequestFuture Timeout

时间:2013-09-09 14:04:37

标签: android request android-volley

使用 RequestFuture 排球时,我遇到了问题。 实际上它只是停在wait(0);在下面的RequestFuture类中的doGet()函数内部,我认为onResponseonErrorResponse永远不会被唤醒。

private synchronized T doGet(Long timeoutMs)
        throws InterruptedException, ExecutionException, TimeoutException {
    if (mException != null) {
        throw new ExecutionException(mException);
    }

    if (mResultReceived) {
        return mResult;
    }

    if (timeoutMs == null) {
        wait(0);
    } else if (timeoutMs > 0) {
        wait(timeoutMs);
    }

    if (mException != null) {
        throw new ExecutionException(mException);
    }

    if (!mResultReceived) {
        throw new TimeoutException();
    }

    return mResult;
}

@Override
public boolean isCancelled() {
    if (mRequest == null) {
        return false;
    }
    return mRequest.isCanceled();
}

@Override
public synchronized boolean isDone() {
    return mResultReceived || mException != null || isCancelled();
}

@Override
public synchronized void onResponse(T response) {
    mResultReceived = true;
    mResult = response;
    notifyAll();
}

@Override
public synchronized void onErrorResponse(VolleyError error) {
    mException = error;
    notifyAll();
}

这是我试图调用上述所有内容的方式。

    RequestFuture<JSONObject> future = RequestFuture.newFuture();
    JsonObjectRequest myReq = new JsonObjectRequest(Request.Method.POST, url, jsonObj, future, future);
    requestQueue.add(myReq);

    try {

        JSONObject response = future.get();
    } catch (InterruptedException e) {
        // handle the error
    } catch (ExecutionException e) {
        // handle the error
    }

我也尝试更换线

requestQueue.add(myReq);

future.setRequest(requestQueue.add(myReq));

future.setRequest(myReq);

也没有帮助。

我已经尝试了一个常用的Volley Request,它使用这个参数就可以了,所以这不应该是原因。 我想问题是,请求永远不会被实际执行,这就是永远不会到达响应侦听器的原因。还试过requestQueue.start(),但没有改变。

我希望我能很好地解释我的问题, 提前谢谢!

4 个答案:

答案 0 :(得分:6)

在get方法中添加超时将能够捕获错误,如果没有给出超时,则会将错误发送回主线程。因此,使用JSONObject response = future.get();更改JSONObject response = future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);应该可以解决问题并将其包装在try catch中以进行超时

答案 1 :(得分:3)

解决!

JSONObject response = future.get();

始终在单独的线程中运行Future Request。它不适用于主线程。我在IntentService中运行Future Request Call,它的工作非常好。

快乐编码:)

答案 2 :(得分:0)

您需要在另一个帖子中调用future.get()。尝试将其包装在AsyncTask中。

查看来源,看起来RequestQueue启动一长串调用来加载响应,最终以RequestFuture.onResponse结尾(后者调用notifyAll通知线程停止等待,如你所提到的)。我认为问题是wait(0)RequestQueue链都在UI线程中运行,所以当调用wait(0)时,RequestQueue链也会等待,所以{{1永远不会被调用,这就是为什么这行只是挂起(因为wait(0)永远等待)。

答案 3 :(得分:0)

除了Blair和Farhan的解决方案之外,在请求中附加重试策略也可以完成这项工作。

request.setRetryPolicy(new DefaultRetryPolicy(RETRY_TIME, RETRY_ATTEMPTS, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));