Замените AsyncTask на Rxjava для базы данных комнат

#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, которую я только что создал, может быть, вы найдете там отличия:

https://github.com/phamtdat/RxRoomDemo

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

1. Спасибо за ответ, я попробовал ваше решение, оно выдало мне следующую ошибку в DAO: Ошибка: не уверен, как обрабатывать возвращаемый тип метода insert. Завершаемые элементы вставки (список <Элементы> элементы);

2. Мне кажется, что вам, возможно, не хватает некоторых зависимостей, пожалуйста, проверьте мой обновленный ответ и посмотрите, поможет ли это.

3. У меня были отсутствующие зависимости, но я по-прежнему получаю ту же проблему: ошибка: не уверен, как обрабатывать возвращаемый тип метода insert. Завершаемые вставки (список <Элементы> элементы); ^[WARN] Требуется инкрементная обработка аннотаций, но поддержка отключена, поскольку следующие процессоры не являются инкрементными: androidx.room. RoomProcessor (ДИНАМИЧЕСКИЙ).

4. извините, kapt это только kotlin. Вы используете java, так что попробуйте annotationProcessor вместо этого (см. Мой отредактированный ответ). Тем временем я проверю, есть ли какие-либо другие проблемы.

5. Отличный ответ! Я бы поместил хотя бы .subscribeOn(Schedulers.io()) в репозиторий, чтобы избежать будущих головных болей по поводу запросов Room, вызываемых в основном потоке, особенно при работе с длинными цепочками действий.