我需要向服务器发送一系列请求。在控制台java应用程序中执行此操作非常简单,因为它只执行等待结果的阻塞请求,评估结果,然后发出下一个请求...
但是,我不知道如何最好地将其移植到Android,因为我需要处理一系列操作,这些操作都在线程中处理,我不能“等待”它们完成。排序代码很好,但如果在嵌套代码中嵌套代码嵌套代码,结果将是一个巨大的阻塞。
正常的顺序是:
在Android中,请求的代码现在如下所示:
JsonObjectRequest jsonRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
int myResult = response.getInt("result");
if (myResult!=0) {
throw new RuntimeException("Bad foo!");
} else {
/* ...and here there's my problem. Here I would
normally create the next step (= the next
"jsonRequest = new JsonObjectRequest..." including the
entailed anonymous handler routine. But that would
lead to a giantly nested code. For you code-gurus:
How to solve that and still produce beautiful
readable code? */
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
MyApplication.getInstance().getRequestQueue().add(jsonRequest);
此外:在控制台应用程序中,可以轻松地将登录代码打包到函数中并将其调用以用于多种用途。例如
private void RenameDaFiles() {
LoginToServer(); // performs an internet request, in volley that starts a thread
GetData();
RenameFiles();
}
private void DeleteDaFiles() {
LoginToServer();
GetSomeOtherData();
DeleteFiles();
}
使用凌空我无法使用该程序方法,因为即使请求未完成,也会立即调用volley返回。我该如何做到最好?
提前多多感谢!
答案 0 :(得分:1)
我问自己同样的问题,这就是我想出的:我在请求链中为每个请求编写了一个私有方法。第一个方法在完成时调用第二个方法,当它完成时调用第三个方法,依此类推。
最后一个方法每次调用传递给下一个方法的结果处理程序。
所以,实际上它与嵌套的匿名类的作用相同。但我认为它更具可读性。
致电代码:
sendFirstRequest(new Consumer<JSONObject>() {
@Override
public void accept(JSONObject result) {
Log.d(TAG, "accept: result = " + result);
}
});
请求链:
private void sendFirstRequest(final Consumer<JSONObject> resultConsumer) {
requestQueue.add(new JsonObjectRequest(
Request.Method.GET,
"www.google.de",
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
sendSecondRequest(resultConsumer); // <-- chaining
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}
));
}
private void sendSecondRequest(final Consumer<JSONObject> resultConsumer) {
requestQueue.add(new JsonObjectRequest(
Request.Method.GET,
"www.google.de",
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
sendLastRequest(resultConsumer); // <-- chaining
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}
));
}
private void sendLastRequest(final Consumer<JSONObject> resultConsumer) {
requestQueue.add(new JsonObjectRequest(
Request.Method.GET,
"www.google.de",
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
resultConsumer.accept(response); // <-- final result
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}
));
}
每当我遇到“异步链问题”时,我都会使用该模式。
为了简化示例,我假设RequestQueue
被定义为字段。
另请注意,像Consumer
这样的Java 8功能接口仅在API级别24之后可用。但是,可以自己定义一个简单版本:
public interface Consumer<T> {
void accept(T t);
}