Я новичок в 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);
}
}




У вас есть два способа вернуть результат.
Первый способ - вызвать метод 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.
вы можете делать все, что захотите, с вашими целями в методе onPostExecute вашего репозитория. если вы хотите использовать его где угодно вне своей assyncTask, вы можете создать глобальную переменную и повлиять на значение в onPostExecute