#android #android-asynctask #rx-java #android-room
#Android #android-asynctask #rx-java #android-room
Вопрос:
Я пытаюсь заменить AsyncTask на RxJava, поскольку Async устарел в Android 11. однако я не могу заставить RxJava работать с Room,
В настоящее время это рабочий код с Asynctask:
В репозитории:
public void insertItems(List<Items> items){
new insertItemsAsyncTask(PrjDao).execute(items);
}
private static class insertItemAsyncTask extends AsyncTask<List<Items>, Void, Void>{
private PrjDao prjDao;
private insertItemAsyncTask(PrjDao prjDao){
this.prjDao = prjDao;
}
@Override
protected Void doInBackground(List<Items>... lists) {
prjDao.insertItems(lists[0]);
return null;
}
}
в DAO
@Insert
void insertItems(List<Items> items);
Я заменил код репозитория на:
public void insertItems(List<Items> items){
Completable.fromAction(() -> prjDao.insertItems(items)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onComplete() {
}
@Override
public void onError(@NonNull Throwable e) {
}
});
}
Однако это не работает, хотя мне удалось получить вывод журнала в onComplete.
Ответ №1:
Попробуйте:
DAO:
@Insert
Completable insertItems(List<Items> items);
Репозиторий:
public void insertItems(List<Items> items){
prjDao.insertItems(items))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...);
}
Или лучше так:
Репозиторий:
public Completable insertItems(List<Items> items){
return prjDao.insertItems(items))
}
А затем подпишитесь на завершаемый и обрабатывайте обратные вызовы подписки там, где вы на самом деле вызываете insertItems()
.
insertItems(items)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...);
На мой взгляд, репозиторий должен предоставлять только мост к интерфейсу БД, а вызывающий должен быть тем, кто обрабатывает обратные вызовы подписки, поскольку каждый вызывающий может захотеть обрабатывать обратные вызовы по-разному.
Обновить
Чтобы использовать rxjava с room, пожалуйста, убедитесь, что у вас есть все необходимые зависимости в вашем файле build.gradle:
implementation "androidx.room:room-runtime:[roomVersion]"
implementation "androidx.room:room-rxjava2:[roomVersion]"
annotationProcessor "androidx.room:room-compiler:[roomVersion]"
В настоящее время я использую roomVersion 2.2.5
Вот простая рабочая демонстрация room rxjava, которую я только что создал, может быть, вы найдете там отличия:
Комментарии:
1. Спасибо за ответ, я попробовал ваше решение, оно выдало мне следующую ошибку в DAO: Ошибка: не уверен, как обрабатывать возвращаемый тип метода insert. Завершаемые элементы вставки (список <Элементы> элементы);
2. Мне кажется, что вам, возможно, не хватает некоторых зависимостей, пожалуйста, проверьте мой обновленный ответ и посмотрите, поможет ли это.
3. У меня были отсутствующие зависимости, но я по-прежнему получаю ту же проблему: ошибка: не уверен, как обрабатывать возвращаемый тип метода insert. Завершаемые вставки (список <Элементы> элементы); ^[WARN] Требуется инкрементная обработка аннотаций, но поддержка отключена, поскольку следующие процессоры не являются инкрементными: androidx.room. RoomProcessor (ДИНАМИЧЕСКИЙ).
4. извините,
kapt
это только kotlin. Вы используете java, так что попробуйтеannotationProcessor
вместо этого (см. Мой отредактированный ответ). Тем временем я проверю, есть ли какие-либо другие проблемы.5. Отличный ответ! Я бы поместил хотя бы
.subscribeOn(Schedulers.io())
в репозиторий, чтобы избежать будущих головных болей по поводу запросов Room, вызываемых в основном потоке, особенно при работе с длинными цепочками действий.