Лучший способ кэширования данных в Android с помощью ViewModel и RxJava2
В моем приложении я использую RxJava2 и новый класс от компонентов архитектуры ViewModel. В моем случае мне нужно перенести SQL-предложение в ViewModel, что сделает магию и вернет Observable, который даст мне данные, которые мне нужны. Все работает нормально, но я не уверен, что использую RX наилучшим образом.
Мой поток данных: ViewModel имеет PublishSubject, на котором я нажимаю SQL. ViewModel также имеет Observable, который создается путем сопоставления темы. Также я использовал DifferentUntilChanged для Subject, чтобы предотвратить повторное выполнение того же запроса. Для кеширования данных я использовал replay(1).autoconnect(1) в Observable, но у этого подхода был недостаток. Иногда мой субъект выдвигал Sql, когда Observable еще не был подключен, и мои данные никогда не доходили до меня. Должен ли я использовать BehaviourSubject? Или, может быть, я не должен использовать replay(1).autoconnect(1) в первую очередь? Или, может быть, весь мой поток не так? Пример:
val listSubject: Subject<RawSql> = PublishSubject.create()
val sqlListEmitter: Observable<List<T>> =
listSubject
.subscribeOn(Schedulers.computation())
.map { // SOME MAGIC HERE }
.replay(1).autoConnect(1, { compositeDisposable.add(it) })
1 ответ
В твоем случае autoConnect()
просто ждет первой подписки на connect()
в ваш поток. Поскольку ваш субъект и ваш поток создают внутреннюю сущность, вы можете вообще не ждать его и вместо этого напрямую подключать.
val listSubject: Subject<RawSql> = PublishSubject.create()
val sqlListEmitter: Observable<List<T>> =
listSubject
.observeOn(Schedulers.computation())
.map { // SOME MAGIC HERE }
.replay(1)
.let {
it.connect(compositeDisposable::add)
it.publish()
}
Также вам может потребоваться изменить subscribeOn()
в observeOn()
, Субъект отправляет в тот же поток, что и данные, помещенные в него, и не учитывает поток, на который он подписан.