У меня возникла проблема с тем, как вернуть значение асинхронного соединения.Возвращаемое значение async-соединения
Что я хочу сделать, так это создать функцию (например, «getById»), которая запрашивает сервер и возвращает объект, содержащий ответ сервера.
Я пробовал со многими различными HTTP-клиентами, но то, что я получаю, это просто возможность создать локальную переменную/взаимодействовать с пользовательским интерфейсом, но не вернуть значение.
Основная архитектура, используемая почти для всех клиентов Http: создание запроса, обработка его обработчиком запроса и передача ему обработчика ответа, который будет обрабатывать ответ.
Что происходит, так это то, что я не могу получить ответ от обработчика запроса и не обнаруживать, когда запрос закончен, чтобы взаимодействовать с ответом; с другой стороны, из обработчика ответа я могу использовать ответ, чтобы внести изменения в пользовательский интерфейс или сохранить его локально, но я не могу вернуть его пользователю как результат функции.
Есть ли способ избежать такого поведения или обходить/взломать его?
Я пытался в основном 4 способа:
- Использование фьючерсных & FutureTasks. Проблема: я могу вызвать их только на обработчике запросов, и поэтому я не могу обнаружить, когда ответ готов, но только когда обработчик запроса готов.
- Использование обратных вызовов. Проблема: то же, что и для фьючерсов и FutureTasks.
- Используйте некоторое время (правда), проверяя, готов ли ответ. Хотя это может работать теоретически, практически он вызывает блок на основном потоке, и поэтому приложение замерзает и будет зависеть вечно от while (true), потому что оно не может выполнить код, который бы разблокировал его.
- Использование многопоточности. Это предотвращает блокировку основного потока, но проблема в том, что поток не может вернуть значение, и обработчик ответа не может получить доступ к блокировке, используемой в другом потоке (или, как кажется), поэтому я не могу сообщить об этом фоновая задача завершена.
Есть ли способ, который я не рассматривал, или кто-нибудь, что, возможно, я неправильно выполнил?
Некоторые примеры кода; В этом коде я использую клиент 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;
}
Этот пример терпит неудачу, потому что значение возвращается до него доступны.
Вы уже, его называют класс AsyncTask и обрабатывает все. – Nanoc
http://developer.android.com/reference/android/os/AsyncTask.html – Fildor
Как бы вы использовали AsyncTask для улучшения этого кода? На мой взгляд, если вы включите его в AsyncTask, вы столкнетесь с той же проблемой, но внутри этого класса, потому что вам все равно понадобится способ сообщить, что ответ готов. – tenik