同时异步任务
Simultaneous AsyncTasks
我正在开发一个 android 应用程序,它必须同时向服务器发出多个 http 请求,所以我决定使用 okhttp 库来发出请求。
问题是当我尝试同时发出一些请求时,我必须等到第一个请求完成后才能执行以下操作。
我正在创建 运行 AsyncTasks,我从中调用以下方法:
public class ApiRestClient {
public static void get(String url, Map<String, String> params, Api.ApiCallback callback) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS).build();
try {
HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
for (Map.Entry<String, String> e : params.entrySet()) {
builder.addQueryParameter(e.getKey(), e.getValue());
}
Request request = new Request.Builder()
.url(builder.build())
.get()
.build();
Response response = client.newCall(request).execute();
if (response.code() == HttpURLConnection.HTTP_OK) {
JSONObject data = new JSONObject(response.body().string());
if (callback != null) {
try {
try {
callback.onSuccess(data);
} catch (JSONException ex){
throw new ApiException(data, ex);
}
} catch (ApiException ex) {
callback.onFail(ex);
}
}
} else {
if (callback != null) {
callback.onFail(new ApiException(response.code()));
}
}
} catch (JSONException | IOException e) {
Log.e(ApiRestClient.class.getSimpleName(), "ApiRestClient.get", e);
if (callback != null) {
callback.onFail(new ApiException(ApiException.SC_INTERNAL_SERVER_ERROR,e));
}
}
}
public static void post(String url, Map<String, String> params, Api.ApiCallback callback) {
try {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS).build();
HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
FormBody.Builder formBuilder = new FormBody.Builder();
for (Map.Entry<String, String> e : params.entrySet()) {
formBuilder.add(e.getKey(), e.getValue());
}
RequestBody body = formBuilder.build();
Request request = new Request.Builder()
.url(builder.build())
.post(body)
.build();
Response response = client.newCall(request).execute();
if (response.code() == HttpURLConnection.HTTP_OK) {
JSONObject data = new JSONObject(response.body().string());
if (callback != null) {
try {
callback.onSuccess(data);
} catch (ApiException ex){
callback.onFail(ex);
}
}
} else {
if (callback != null) {
callback.onFail(new ApiException(response.code()));
}
}
} catch (JSONException | IOException e) {
Log.e(ApiRestClient.class.getSimpleName(), "ApiRestClient.post", e);
if (callback != null) {
callback.onFail(new ApiException(HttpURLConnection.HTTP_INTERNAL_ERROR,e));
}
}
}
}
这是 AsyncTask 代码:
public class ApiMethods extends AsyncTask<String, Integer, Boolean> {
private RequestMethod requestMethod;
private String serverURL;
private Api.ApiCallback callback;
private Map<String, String> requestParams;
public ApiMethods(RequestMethod requestMethod, String serverURL, Map<String, String> requestParams, Api.ApiCallback callback) {
this.requestMethod = requestMethod;
this.serverURL = serverURL;
this.callback = callback;
this.requestParams = requestParams;
}
@Override
protected Boolean doInBackground(String... params) {
switch (this.requestMethod) {
case GET:
ApiRestClient.get(serverURL, requestParams, callback);
break;
case POST:
ApiRestClient.post(serverURL, requestParams, callback);
break;
default:
break;
}
return true;
}
public enum RequestMethod {
GET, POST
}
}
来自 AsyncTask
文档:
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[])
with THREAD_POOL_EXECUTOR
.
所以如果你有
ApiMethods apiMethods = new ApiMethods();
改变
apiMethods.execute(params);
到
apiMethods.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
来自 executeOnExecutor
文档:
Warning: Allowing multiple tasks to run in parallel from a thread pool is generally not what one wants, because the order of their operation is not defined. For example, if these tasks are used to modify any state in common (such as writing a file due to a button click), there are no guarantees on the order of the modifications. Without careful work it is possible in rare cases for the newer version of the data to be over-written by an older one, leading to obscure data loss and stability issues. Such changes are best executed in serial; to guarantee such work is serialized regardless of platform version you can use this function with SERIAL_EXECUTOR.
我正在开发一个 android 应用程序,它必须同时向服务器发出多个 http 请求,所以我决定使用 okhttp 库来发出请求。
问题是当我尝试同时发出一些请求时,我必须等到第一个请求完成后才能执行以下操作。
我正在创建 运行 AsyncTasks,我从中调用以下方法:
public class ApiRestClient {
public static void get(String url, Map<String, String> params, Api.ApiCallback callback) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS).build();
try {
HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
for (Map.Entry<String, String> e : params.entrySet()) {
builder.addQueryParameter(e.getKey(), e.getValue());
}
Request request = new Request.Builder()
.url(builder.build())
.get()
.build();
Response response = client.newCall(request).execute();
if (response.code() == HttpURLConnection.HTTP_OK) {
JSONObject data = new JSONObject(response.body().string());
if (callback != null) {
try {
try {
callback.onSuccess(data);
} catch (JSONException ex){
throw new ApiException(data, ex);
}
} catch (ApiException ex) {
callback.onFail(ex);
}
}
} else {
if (callback != null) {
callback.onFail(new ApiException(response.code()));
}
}
} catch (JSONException | IOException e) {
Log.e(ApiRestClient.class.getSimpleName(), "ApiRestClient.get", e);
if (callback != null) {
callback.onFail(new ApiException(ApiException.SC_INTERNAL_SERVER_ERROR,e));
}
}
}
public static void post(String url, Map<String, String> params, Api.ApiCallback callback) {
try {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS).build();
HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
FormBody.Builder formBuilder = new FormBody.Builder();
for (Map.Entry<String, String> e : params.entrySet()) {
formBuilder.add(e.getKey(), e.getValue());
}
RequestBody body = formBuilder.build();
Request request = new Request.Builder()
.url(builder.build())
.post(body)
.build();
Response response = client.newCall(request).execute();
if (response.code() == HttpURLConnection.HTTP_OK) {
JSONObject data = new JSONObject(response.body().string());
if (callback != null) {
try {
callback.onSuccess(data);
} catch (ApiException ex){
callback.onFail(ex);
}
}
} else {
if (callback != null) {
callback.onFail(new ApiException(response.code()));
}
}
} catch (JSONException | IOException e) {
Log.e(ApiRestClient.class.getSimpleName(), "ApiRestClient.post", e);
if (callback != null) {
callback.onFail(new ApiException(HttpURLConnection.HTTP_INTERNAL_ERROR,e));
}
}
}
}
这是 AsyncTask 代码:
public class ApiMethods extends AsyncTask<String, Integer, Boolean> {
private RequestMethod requestMethod;
private String serverURL;
private Api.ApiCallback callback;
private Map<String, String> requestParams;
public ApiMethods(RequestMethod requestMethod, String serverURL, Map<String, String> requestParams, Api.ApiCallback callback) {
this.requestMethod = requestMethod;
this.serverURL = serverURL;
this.callback = callback;
this.requestParams = requestParams;
}
@Override
protected Boolean doInBackground(String... params) {
switch (this.requestMethod) {
case GET:
ApiRestClient.get(serverURL, requestParams, callback);
break;
case POST:
ApiRestClient.post(serverURL, requestParams, callback);
break;
default:
break;
}
return true;
}
public enum RequestMethod {
GET, POST
}
}
来自 AsyncTask
文档:
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke
executeOnExecutor(java.util.concurrent.Executor, Object[])
withTHREAD_POOL_EXECUTOR
.
所以如果你有
ApiMethods apiMethods = new ApiMethods();
改变
apiMethods.execute(params);
到
apiMethods.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
来自 executeOnExecutor
文档:
Warning: Allowing multiple tasks to run in parallel from a thread pool is generally not what one wants, because the order of their operation is not defined. For example, if these tasks are used to modify any state in common (such as writing a file due to a button click), there are no guarantees on the order of the modifications. Without careful work it is possible in rare cases for the newer version of the data to be over-written by an older one, leading to obscure data loss and stability issues. Such changes are best executed in serial; to guarantee such work is serialized regardless of platform version you can use this function with SERIAL_EXECUTOR.