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