Добрый вечер!
Есть метод, который делает поисковый запрос на сервер и при помощи ответа наполняет MatrixCursor, который используется для вывода подсказок.
Для обращения к серверу используется библиотека LoopJ AsyncHttpClient
MatrixCursor searchForSuggestions(String query){
MatrixCursor cursor = new MatrixCursor(columns);
RequestParams params = new RequestParams();
params.add("name", query);
get("http://███████████████.tk/api/medicament/search", params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
if (response.length() > 0) {
try {
for (int i = 0; i < 4 && i < response.length(); i++) {
JSONObject object = response.getJSONObject(i);
Object[] values = {i, object.getString("title"), object.getJSONArray("medicaments").getInt(0)};
cursor.addRow(values);
Log.d(TAG, "onSuccess: in the loop");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
}
});
Log.d(TAG, "searchForSuggestions: ok");
return cursor;
Проблема в том, что этот метод не ждёт, пока закончится запрос и наполнится курсор, поэтому возвращает его пустым (в LogCat сообщение "searchForSuggestions: ok" появляется раньше, чем "onSuccess: in the loop"). Как следствие, подсказки не отображаются. Как сделать, чтобы onSuccess выполнялся раньше, чем завершается основной метод?
У меня для вас неприятные новости: AsyncHttpClient.get() - это асинхронный запрос, то есть запускается в параллельном потоке, а с недавних пор (с API 19 по-моему) - не асинхронные сетевые вызовы запрещены..., то есть даже если вы вручную начнете лепить синхронный GET - то приложение все равно вывалится с Exception'ом что у вас сетевой вызов в UI треде. Именно по этой причине у вас onSuccess() заканчивается после уже после того как у UI что-то отработает.
Выхода вижу 2:
onSuccess() правда надо будет предпринять специальные меры, что система не ругалась, что вы обновляете не из UI тредаКардинально пересмотреть архитектуру приложения, а именно:
а) вынести все сетевое чтение в Service, которые в фоне наполняют локальную копию удаленной БД
б) а все запросы, которые вы хотели делать к сети - делать к локальной SQLite
Я бы рекомендовал пойти по 2-му пути - это как бы стандартный и рекомендованный Гуглом паттерн.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости