Я хочу сопоставить результаты своей области с неизменяемой моделью представления и хочу прослушать изменения результатов, поэтому я испускаю их PublishSubject. Однако данные не отображаются в моем представлении recyclerview, пока я не поверну устройство, эта проблема исправлено, когда я удаляю observeOn(AndroidSchedulers.mainThread())
.
Репозиторий:
fun notionsChanges(state: Boolean): Observable<Pair<MutableList<Notion>, OrderedCollectionChangeSet?>> {
val notionsChanges = PublishSubject.create<Pair<MutableList<Notion>, OrderedCollectionChangeSet?>>()
val realm = Realm.getDefaultInstance()
val queryResult = realm.where<Notion>()
.equalTo("isArchived", state)
.findAllAsync()
val listener: OrderedRealmCollectionChangeListener<RealmResults<Notion>> = OrderedRealmCollectionChangeListener { realmResults, changeSet ->
if (realmResults.isValid && realmResults.isLoaded) {
val results: MutableList<Notion> = realm.copyFromRealm(realmResults)
notionsChanges.onNext(results to changeSet)
}
}
queryResult.addChangeListener(listener)
notionsChanges.doFinally {
queryResult.removeChangeListener(listener)
closeRealm(realm)
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
return notionsChanges
}
в моем ведущем я использую это наблюдаемое, чтобы сопоставить модель с моделью представления, затем я показываю (при подписке) данные в recyclerview внутри фрагмента:
private var subscriptions: CompositeDisposable = CompositeDisposable()
override fun onResume() {
super.onResume()
showData()
}
override fun onPause() {
subscriptions.clear()
super.onPause()
}
private fun showData() {
val viewModel = present(idleStates, resources, isIdle)
with(viewModel) {
subscriptions.addAll(
notionsChanges.subscribe(notionsAdapter::handleChanges),
//other subscriptions.
)
}
}
notionsAdapter.handleChanges:
fun handleChanges(collectionChange: Pair<List<NotionCompactViewModel>, OrderedCollectionChangeSet?>) {
val (collection, changeset) = collectionChange
debug("${collection.size}") //correctly prints the actual size of the collection.
replaceAll(collection)
if (changeset == null)
notifyDataSetChanged()
else {
for (change in changeset.changeRanges)
notifyItemRangeChanged(change.startIndex, change.length)
for (insertion in changeset.insertionRanges)
notifyItemRangeInserted(insertion.startIndex, insertion.length)
for (deletion in changeset.deletionRanges)
notifyItemRangeRemoved(deletion.startIndex, deletion.length)
}
}
извините, если код неясен.
редактировать: мой onBindViewHolder
иногда не вызывается (конечно, когда recyclerview пуст).
findAllAsync
иaddChangeListener
не поддерживаются в потоках без цикла, это должно выполняться в планировщике, созданном из цикла HandlerThread. - person EpicPandaForce   schedule 06.09.2018subscribeOn(io())
обманул меня. Тогда это просто небезопасно для больших наборов данных. Упс! Вы уверены, что вместо этого не следует использовать BehaviorSubject? - person EpicPandaForce   schedule 06.09.2018state == INITIAL
. - person EpicPandaForce   schedule 06.09.2018copyFromRealm()
в потоке пользовательского интерфейса может вызвать ANR с большим набором данных, поэтому я рекомендовал HandlerThread в другом ответе, который вы связали. - person EpicPandaForce   schedule 06.09.2018