2015-11-13 2 views
-2

У меня возникла проблема с тем, как вернуть значение асинхронного соединения.Возвращаемое значение async-соединения

Что я хочу сделать, так это создать функцию (например, «getById»), которая запрашивает сервер и возвращает объект, содержащий ответ сервера.

Я пробовал со многими различными HTTP-клиентами, но то, что я получаю, это просто возможность создать локальную переменную/взаимодействовать с пользовательским интерфейсом, но не вернуть значение.

Основная архитектура, используемая почти для всех клиентов Http: создание запроса, обработка его обработчиком запроса и передача ему обработчика ответа, который будет обрабатывать ответ.

Что происходит, так это то, что я не могу получить ответ от обработчика запроса и не обнаруживать, когда запрос закончен, чтобы взаимодействовать с ответом; с другой стороны, из обработчика ответа я могу использовать ответ, чтобы внести изменения в пользовательский интерфейс или сохранить его локально, но я не могу вернуть его пользователю как результат функции.

Есть ли способ избежать такого поведения или обходить/взломать его?

Я пытался в основном 4 способа:

  1. Использование фьючерсных & FutureTasks. Проблема: я могу вызвать их только на обработчике запросов, и поэтому я не могу обнаружить, когда ответ готов, но только когда обработчик запроса готов.
  2. Использование обратных вызовов. Проблема: то же, что и для фьючерсов и FutureTasks.
  3. Используйте некоторое время (правда), проверяя, готов ли ответ. Хотя это может работать теоретически, практически он вызывает блок на основном потоке, и поэтому приложение замерзает и будет зависеть вечно от while (true), потому что оно не может выполнить код, который бы разблокировал его.
  4. Использование многопоточности. Это предотвращает блокировку основного потока, но проблема в том, что поток не может вернуть значение, и обработчик ответа не может получить доступ к блокировке, используемой в другом потоке (или, как кажется), поэтому я не могу сообщить об этом фоновая задача завершена.

Есть ли способ, который я не рассматривал, или кто-нибудь, что, возможно, я неправильно выполнил?

Некоторые примеры кода; В этом коде я использую клиент Android-Асинхронный-Http от Loopj, доступный here:

public JSONObject getById(String url, String id) { 

    JSONObject jo = null; 

    AsyncHttpClient client = new AsyncHttpClient(); 

    final AsyncHttpResponseHandler ahrh = new AsyncHttpResponseHandler() { 
     @Override 
     public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
      try { 
       jo = new JSONObject(new String(responseBody, "UTF-8")); 
      } catch (JSONException | UnsupportedEncodingException e) { 
      } 
     } 

     @Override 
     public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
     } 
    }; 

    client.get(url + id, ahrh); 

    return jo; 

} 

Этот пример терпит неудачу, потому что значение возвращается до него доступны.

+3

Вы уже, его называют класс AsyncTask и обрабатывает все. – Nanoc

+0

http://developer.android.com/reference/android/os/AsyncTask.html – Fildor

+0

Как бы вы использовали AsyncTask для улучшения этого кода? На мой взгляд, если вы включите его в AsyncTask, вы столкнетесь с той же проблемой, но внутри этого класса, потому что вам все равно понадобится способ сообщить, что ответ готов. – tenik

ответ

1

Вы пытались использовать asyncTask? Используется для выполнения операции в фоновом режиме, избегая замораживания пользовательского интерфейса. Вам необходимо расширить класс AsyncTask, переопределить метод doInBackground, в котором вы выполняете запрос Http и метод onPostExecute для обновления пользовательского интерфейса в основном потоке.

Посмотрите here

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