【问题标题】:How to use realm with RxJava2如何在 RxJava2 中使用领域
【发布时间】:2018-01-31 07:28:16
【问题描述】:

我在我的项目中使用 RxJava 2 和 Realm,并且我正在使用 Observable 从 RealmResults 中获取数据。这是我的代码。

fun getAllAsync(){
    realm?.where(RealmSuggestedFriends::class.java)
            ?.findAllAsync()
            ?.asFlowable()
            ?.filter { t -> t.isLoaded }
            ?.observeOn(AndroidSchedulers.mainThread())
            ?.subscribe({
        t: RealmResults<RealmSuggestedFriends>? ->for (firstResults in t!!){
        val requestPojo = RequestPojo()
        requestPojo.email = firstResults.friendEmail
        requestPojo.image = firstResults.friendImage
        requestPojo.name = firstResults.friendName
        requestPojo.status = firstResults.friendStatus
        requestPojo.thumb_image = firstResults.friendThumbImage
        requestPojo.uid = firstResults.friendUid
        userAdapter?.addData(requestPojo)
    }
    },{
        t: Throwable? ->
      },
      {},
      {})
    }

我尝试了上面的代码,但没有得到任何数据。在此之后,我尝试通过这种方式获取数据

Observable.create<RealmSuggestedFriends> { emitter ->
        val results = realm?.where(RealmSuggestedFriends::class.java)
                ?.findAllAsync()
        for (suggestedFriends in results!!){
            emitter.onNext(suggestedFriends)
        }
        emitter.onComplete()
    }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap { firstResults ->
                val requestPojo = RequestPojo()
                requestPojo.email = firstResults.friendEmail
                requestPojo.image = firstResults.friendImage
                requestPojo.name = firstResults.friendName
                requestPojo.status = firstResults.friendStatus
                requestPojo.thumb_image = firstResults.friendThumbImage
                requestPojo.uid = firstResults.friendUid
                Observable.just(requestPojo).subscribeOn(Schedulers.io())
            }
            .subscribe({
                t: RequestPojo? ->  userAdapter?.addData(t!!)
            },{
                t: Throwable? ->  
            },{

            },{
                t: Disposable? ->  compositeDisposable?.add(d!!)
            })

也使用此代码,我没有得到任何数据,而且我得到了 Realm accessed from incorrect thread 的祝酒词。任何人都可以帮助我使其工作。提前致谢。

【问题讨论】:

    标签: android kotlin realm observable rx-java2


    【解决方案1】:
    Single.create<List<RealmSuggestedFriends>> { emitter ->
        Realm.getDefaultInstance().use { realm ->
            val results = realm.where(RealmSuggestedFriends::class.java).findAll()
            emitter.onSuccess(realm.copyFromRealm(results))
        }
    }.subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .map { results ->
         for(firstResults in results) {
            val requestPojo = RequestPojo()
            requestPojo.email = firstResults.friendEmail
            requestPojo.image = firstResults.friendImage
            requestPojo.name = firstResults.friendName
            requestPojo.status = firstResults.friendStatus
            requestPojo.thumb_image = firstResults.friendThumbImage
            requestPojo.uid = firstResults.friendUid
         }
     }.subscribe({    
         list: List<RequestPojo> ->  userAdapter.updateData(list)
     },{
         t: Throwable? ->  
     },{
     })
    

    无论如何,假设您不想在领域更改时收到通知。

    否则,使用 Observable,有点像 this one

    private Observable<List<Task>> createResults(QuerySelector<DbTask> querySelector) {
        return Observable.create((ObservableOnSubscribe<List<Task>>) emitter -> {
            Realm realm = Realm.getDefaultInstance();
            final RealmResults<DbTask> dbTasks = querySelector.createQuery(realm);
            final RealmChangeListener<RealmResults<DbTask>> realmChangeListener = element -> {
                if(element.isLoaded() && !emitter.isDisposed()) {
                    List<Task> tasks = mapFrom(element);
                    if(!emitter.isDisposed()) {
                        emitter.onNext(tasks);
                    }
                }
            };
            emitter.setDisposable(Disposables.fromAction(() -> {
                if(dbTasks.isValid()) {
                    dbTasks.removeChangeListener(realmChangeListener);
                }
                realm.close();
            }));
            dbTasks.addChangeListener(realmChangeListener);
        }).subscribeOn(looperScheduler.getScheduler()).unsubscribeOn(looperScheduler.getScheduler());
    }
    

    要让第二个工作,您甚至可以尝试my library that helps with this

    Flowable<List<Dog>> dogs;
    
    @Inject
    Monarchy monarchy;
    
    private List<Dog> currentDogs = Collections.emptyList();
    
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LiveData<List<Dog>> dogs = monarchy.findAllMappedWithChanges(realm -> realm.where(RealmDog.class),
                                                               from -> Dog.create(from.getName()));
        this.dogs = Flowable.fromPublisher(LiveDataReactiveStreams.toPublisher(getActivity(), dogs));
    

    【讨论】:

    • 我喜欢第一个。我会试试看。但我想问一下copyToRealm。你为什么在这里使用,如果同时 Realm 中的数据发生变化,那么我的 RealmResults 会自动更新,否则我将不得不为此使用领域变化监听器。再次感谢..
    • 实际上,你不应该喜欢第一个 :D 但你实际上也可以试试我的库,它可以帮助Rx integration using LiveData's Rx integration,它应该完全符合你的要求。
    • 为什么我不应该使用第一个?这样做有错吗?
    • 因为您不订阅更改 :D 从技术上讲,它从后台线程读取数据并繁荣它是一次性的。我更喜欢订阅,但如果你想映射到另一个对象类型(你这样做!)那么你应该在后台线程上做,对吧?所以你应该看看我添加的关于我的图书馆的编辑,看看它是否适合你。它有一个样本和一切:) 所以它应该!
    • 所以你的意思是如果任何数据发生变化,那么它不会反映在复制的列表中。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多