Запрос базы данных комнат

Я новичок в Room, и я пытаюсь записать query в свой database, чтобы получить от него row. Я попытался сделать это с помощью querying с помощью primary key, который является идентификатором, но проблема в том, что я не знаю, как вернуть целевой object из repository.

Это Dao

@Query("SELECT * FROM targets WHERE id = :id LIMIT 1")
Targets findTargetById(int id);

Это класс репозитория

 public Targets findTarget (int id) {
    new findTargetByIDAsyncTask(mTargetsDao).execute(id);

}

   private static class findTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private TargetsDao mAsyncTaskDao;

    findTargetByIDAsyncTask(TargetsDao dao) {
        mAsyncTaskDao = dao;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {

        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        super.onPostExecute(targets);
    }
}

вы можете делать все, что захотите, с вашими целями в методе onPostExecute вашего репозитория. если вы хотите использовать его где угодно вне своей assyncTask, вы можете создать глобальную переменную и повлиять на значение в onPostExecute

kfir88 09.09.2018 11:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
665
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

У вас есть два способа вернуть результат.

Первый способ - вызвать метод AsyncTask.get(), но он по-прежнему будет содержать MainThread, что приведет к ANR, если задача будет длиться более 5 секунд:

public Targets findTarget (int id) {
    return new findTargetByIDAsyncTask(mTargetsDao).execute(id).get();
}

Второй способ более сложный, но он не будет содержать MainThread. Вам следует добавить класс обратного вызова:

public interface Callback {
        void onSuccess(Targets targets);
    }

Каждый метод вашего репозитория будет выглядеть так:

public void findTarget (Callback callback, int id) {
        new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
    }

А AsynTask будет выглядеть так:

private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private final TargetsDao mAsyncTaskDao;
    private final Callback callback;

    FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
        mAsyncTaskDao = dao;
        this.callback = callback;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {
        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        callback.onSuccess(targets);
    }
}

Дело в том, чтобы получить данные / объект из фонового потока. Вы можете использовать AsyncTask для Android или ExecutorService. Простой пример: если вы хотите получить строку имени пользователя, метод будет:

private String getName() {
    String name = null;
    try {
        name = Executors.newSingleThreadExecutor().submit(() ->
                userDao.fetchUserName()).get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return name;
}

У меня похожий вариант использования. Ваш ответ кажется простым и эффективным. Но я вижу много ответов, которые используют Callable и Future для возврата объекта (см. stackoverflow.com/questions/40658145/…). Буду признателен за ваши мысли о вашем подходе по сравнению с подходом Callable / Future.

AJW 13.04.2021 16:58

Другие вопросы по теме