java - 有没有办法从 "onResponse"函数接收响应对象?

标签 java android

如何从 public void 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;
}

}

最佳答案

您不能完全按照您所写的那样执行此操作,因为网络请求发生在单独的线程上。

首先,让我们浏览一下您的代码,以便您清楚发生了什么:

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 会抛出异常。但是如果您已经在单独的线程上进行工作,这样就可以了。

希望有帮助!

关于java - 有没有办法从 "onResponse"函数接收响应对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54114163/

相关文章:

java - JPA orphanRemoval = true 尝试更新而不是删除

java - eclipse 中的 log4j2.xml 和 log4j2-test.xml

java - 按 map 值分组

android - 如何使 View 50% 透明?

android - 如何使用 Firestore 填充引用字段

android - Android在输出混音上应用音频pcm过滤器

java - Android 上的 getType

java - 使用表中的长整数格式化单元格

java - 图像上弹出文本的 CSS 帮助

java - 在 Kotlin 中存储日期和时间的最佳方式