2016-08-16 4 views
0

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

Итак, я просто получил этот объект из ленивого 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 части запроса внутри транзакций асинхронных.

Редактировать. На самом деле, он бросает 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 
      } 
     } 
    } 
+0

Я в основном удивлен, что это не просто врезаться в целом, говорю, что вы пытаетесь добавить изменения слушателя на не нити петлителя, или что вы обращаетесь объект Realm фонового потока от пользовательского интерфейса нить. – EpicPandaForce

+0

ya. realm edit please –

+0

любая идея, почему нужно давать доступ к различным потокам при редактировании 2? –

ответ

1

Все в 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 
    } 
} 
+0

ok. но в любом случае это не сработает. Подумайте, потому что я получаю новый свежий экземпляр realm в основных потоках, а затем я использую его в потоке bg. Ошибка: java.lang.IllegalStateException: доступ к Realm из неправильного потока. Объекты Realm могут быть доступны только в потоке, который они были созданы. –

+0

.... это не должно быть в случае с ** этим ** кодом, который я написал, поэтому я думаю, что авария происходит из другого места. – EpicPandaForce

+0

попытался это и работает: Observable.just (Itemid) .subscribeOn (Schedulers.io()) .subscribe { Вэл область = Realm.getDefaultInstance() realm.executeTransaction { realm.where (ItemRealm :: класс. java) .findFirst(). userDeleted = true } } –

Смежные вопросы