2016-12-21 7 views
0

Я разрабатываю приложение для Android, которое должно выполнять несколько одновременных HTTP-запросов на сервере, поэтому я решил использовать библиотеку okhttp для выполнения запросов.Синхронные AsyncTasks

Проблема заключается в том, что когда я пытаюсь выполнить какой-либо запрос одновременно, мне нужно подождать до завершения первого завершения, чтобы выполнить следующее.

Я создание и запуск 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 
    } 
} 

ответ

1

Из AsyncTask документов:

Когда впервые введенные, AsyncTasks выполнялись последовательно на одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи выполняются в одном потоке, чтобы избежать ошибок обычного приложения, вызванных параллельным выполнением.

Если вы действительно хотите выполнить параллельное выполнение, вы можете вызвать executeOnExecutor(java.util.concurrent.Executor, Object[]) с помощью THREAD_POOL_EXECUTOR.

Так что, если у вас

 ApiMethods apiMethods = new ApiMethods(); 

Изменить

 apiMethods.execute(params); 

в

 apiMethods.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); 

С executeOnExecutor документ:

Предупреждение: Разрешение нескольких задач, выполняемых параллельно из пула потоков, обычно не является тем, что требуется, поскольку порядок их работы не определен. Например, если эти задачи используются для изменения общего состояния (например, для записи файла из-за нажатия кнопки), нет никаких гарантий в отношении порядка модификаций. Без тщательной работы в редких случаях, когда более новая версия данных может быть переписана более старой версией, что приводит к неясным проблемам потери данных и стабильности. Такие изменения лучше всего выполнять в серийном режиме; чтобы гарантировать, что такая работа сериализована независимо от версии платформы, вы можете использовать эту функцию с SERIAL_EXECUTOR.

 Смежные вопросы

  • Нет связанных вопросов^_^