有没有办法从“ onResponse”功能中接收responseObject?

时间:2019-01-09 16:11:12

标签: java android

如何从公开的onResponse函数中获取响应?

编辑:我得到了解析错误:“无法为最终变量'res'赋值”

public JSONObject getRestRequest() {
    final JSONObject res; 

    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, this.restPath, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) { // basically I just want to return this response
            res = response;
        }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        }
    );
    return res;
}

}

2 个答案:

答案 0 :(得分:0)

您正在尝试立即获得结果,但是请求是异步的,您可以同步调用请求

synchronized (this) {
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, "", null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) { // basically I just want to return this response
            res = response;
            YourClassName.this.notify();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    }
    );
    this.wait();
}

但是它将锁定您的线程,直到请求完成 我确定您需要异步进行 请阅读有关Java多线程的文档

答案 1 :(得分:0)

由于网络请求是在单独的线程上发生的,因此您不能完全按照您的描述进行操作。

首先,让我们遍历代码,以便清楚发生了什么事情:

public JSONObject getRestRequest() { // 1 - your method is invoked by another method and control starts here
    final JSONObject res; // 2 - This final (i.e. immutable) field is created

    // 3 - You create a new request object - no networking is happening yet
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, this.restPath, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) { // basically I just want to return this response
            // 5 - Some time later, after the request completes, this method is invoked
            // BUT - you can't assign to res because it's final (immutable)
            res = response;
        }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        }
    );

    // 4 - IMMEDIATELY after creating "request", the value that was created in step 2 (which is null) is returned
    return res;
}

因此,您尝试同步执行异步操作(启动线程以发出网络请求并解析响应)(阻塞直到完成返回结果)。

那是你的问题。要解决此问题,您有两种选择:

1-使用异步回调:

public void getRestRequest(final Callback<JSONObject> callback) { // 1 - your method is invoked by another method and control starts here
    // Now you're passing in a callback that will be invoked later with the result
    // final JSONObject res; // 2 - You no longer need this local variable

    // 3 - You create a new request object - no networking is happening yet
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, this.restPath, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) { // basically I just want to return this response
            // 5 - Some time later, after the request completes, this method is invoked
            // This time, you invoke your callback with the result
            callback.onSuccess(response)
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                // 6 - You can also pass back errors to your callback
                callback.onError(error);
            }
        }
    );

    // 4 - You return IMMEDIATELY after creating "request"
}

此方法更为常见。创建回调,将其传递给函数,然后处理响应:

// 1 - Start showing some UI that a request is happening
showProgressDialog();

// 2 - A new callback to handle the network response is created - no request is happening yet
Callback<JSONObject> callback = new Callback<>() {
    public void onSuccess(JSONObject response) {
        // 4 - Some time later, when the network response finishes, this called
        // Handle response
        dismissProgressDialog(); // Back on the main thread, so safe to update the UI
    }

    public void onError(VolleyError error) {
        // 5 - Or this is called if the request failed
        // Handle error
        dismissProgressDialog(); // Back on the main thread, so safe to update the UI
    }
}
// 3 - Invoke the network request which will happen in a background thread.
// Meanwhile, the main (UI) thread is not blocked and the progress dialog continues to spin
network.getRestRequest(callback)

选项2-使用RequestFuture

public JSONObject getRestRequest() { // 1 - your method is invoked by another method and control starts here
    // 2 - Initialize a Future to use to synchronously get the result
    RequestFuture<JSONObject> future = RequestFuture.newFuture();

    // 3 - You create a new request object with the future as the listener - no networking is happening yet
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, this.restPath, future, future);

    // 4 - You return the value the future will obtain by making the network request
    // THIS IS A BLOCKING CALL SO DON'T DO THIS ON THE MAIN THREAD
    // This will also throw an exception if it fails
    return future.get();
}

因此,现在您可以得到最初想要的结果:

...
JSONObject response = network.getRestRequest()
...

但是您不能在主(UI)线程上执行此操作(如果尝试在主线程上进行联网,则Android会引发异常。但是,如果您已经在单独的线程上进行工作, ,这很好。

希望有帮助!