作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何从 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/
我是一名优秀的程序员,十分优秀!