Страницы

Поиск по вопросам

суббота, 15 февраля 2020 г.

Доступ к ListView из другого потока

#java #android #многопоточность #android_studio


Запускаю метод загрузки данных из БД из потока 

Thread thread = new Thread(new Runnable() {
@Override
public void run() {
    getAvailableRecipes();
    }
});
thread.start();


В данном методе происходит присвоение адаптера ListView, но в итоге получаю ошибку,
что сделать это можно из UI-потока. Каким образом я могу получить доступ к ListView
и другого потока? В C# эта проблема решалась с помощью делегатов, а как обстоят дела
в java? Воспроизвести по аналогии вряд ли смогу, поскольку с java на "вы". Есть ли
какие-то отработанные методы решения данной проблемы?
    


Ответы

Ответ 1



Разделите этот метод на два: загрузка данных (долгая операция) обновление UI (в вашем случае это присвоение адаптера) Вторую часть нужно выполнять в UI потоке, можно, например, воспользоваться методом runOnUiThread (русская статья про этот метод): void getAvailableRecipes() { ... загрузка данных ... activity.runOnUiThread(new Runnable() { ... обновление UI ... }); } Так как такой паттерн: Запустить долгую задачу в фоновом потоке Изменить что-то в UI на основе результатов задачи часто встречается в андроид-приложениях, то разработчики придумали специальный класс AsyncTask, значительно упрощающий жизнь. Вот русская статья про него. Код с ним выглядит примерно так: new AsyncTask { protected Result doInBackground(Params... params) { ... долгая фоновая операция ... } protected void onProgressUpdate(Progress... progress) { ... обновление прогресса (можно оставить метод пустым) ... } protected void onPostExecute(Result result) { ... обновление UI ... } }().execute(param1, param2, ...) Некоторые пояснения: Params — класс параметров, которые вы будете передавать в execute. Можно не передавать никаких параметров и использовать Void Progress — класс, на основе которого будет обновляться прогресс (например, если AsyncTask скачивает файл, то это может быть Integer, представляющий процент скачанного). Можно никак не отображать прогресс и использовать Void Result — класс, который возвращает метод doInBackground и который принимает метод onPostExecute

Комментариев нет:

Отправить комментарий