Android Kotlin Realm Правильный способ запроса + обновление Async

Недавно я столкнулся с проблемой, в которой я имел в памяти список объектов RealResult и показывал его в представлении. При нажатии пользователем текущий отображаемый элемент должен быть помечен как удаленный в области (свойство isDeleted )

Так что я просто получал этот объект из ленивого списка RealmResults , открывал транзакцию и RealmResults ее удаление. Когда RealmResults автоматически обновляется, у меня был прослушиватель изменений, связанный с notifityDataSetChanged . Все работает отлично, за исключением этого предупреждения:

 Mixing asynchronous queries with local writes should be avoided. Realm will convert any async queries to synchronous in order to remain consistent. Use asynchronous writes instead 

Это проблематично, потому что мой список огромен, и я не хочу, чтобы запрос стал sync . Я решил это так, что я не знаю, что это правильно. Вместо предоставления объекту элемента функции обновления, я даю идентификатор объекта, а затем делаю это:

 Realm.getDefaultInstance().use { realm -> realm.executeTransactionAsync { // find the item realm.where(ItemRealm::class.java) .equalTo(ItemRealm.ID, itemId).findFirstAsync() .addChangeListener(object : RealmChangeListener<ItemRealm> { override fun onChange(element: ItemRealm) { element.deleted = true element.removeChangeListener(this) } }) } } 

Проблема, которая нестабильна, является async частью запроса внутри транзакции async.

Редактировать. На самом деле, он бросает java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

Edit2: пробовал это и показывал доступ к Realm в другом потоке:

 fun setItemDeleted(itemId: Long) { // write so new realm instance Realm.getDefaultInstance().use { realm -> realm.executeTransactionAsync { // find the item val item = realm.where(ItemRealm::class.java) .equalTo(ItemRealm.TIMESTAMP, itemId).findFirst() item?.userDeleted = true } } } 

Все в executeTransactionAsync() работает в фоновом потоке, поэтому вы должны использовать синхронные методы для получения вашего объекта внутри него.

 Realm.getDefaultInstance().use { realm -> realm.executeTransactionAsync { bgRealm -> // find the item val item = bgRealm.where(ItemRealm::class.java) .equalTo(ItemRealm.ID, itemId).findFirst() item?.deleted = true } } 
Intereting Posts
Конструктор, принимающий конструктивный конструктор в производном классе Котлин Kotlin и TornadoFX: привязать наблюдаемое свойство к функции коллекции? Kotlin – getPendingIntent с синтаксисом нескольких флагов Nullablity DB генерирует атрибуты Форма входа с повторным запросом на rxJava и дооснащение Каковы преимущества сопутствующего объекта над простым объектом? Невозможно использовать локальный обработчик аннотаций в проекте Android kotlin Установить и получить свойство непосредственно в делегате Kapt не работает с AutoValue в Android Studio 3.0 Могу ли я применять функцию infix внутри собственного класса без этого? Котлин, выполняемый в потоке, использует другое значение, чем прошедшее Kapt + LoganSquare не работает должным образом при сопоставлении Как распределить конфигурацию котла Kotlin по нескольким проектам Gradle? переместить вид в зависимости от направления движения Создание несвязанного сервиса в Котлине