简体   繁体   中英

Android Realm Update Asynchronously Using RxJava

I have this query to update data already in my realm table;

for (MyGameEntrySquad squad : response.body().getSquad()) {
            subscription = realm.where(RealmPlayer.class).equalTo("id", squad.getPlayer().getId())
                    .findFirstAsync()
                    .asObservable()
                    .subscribe(new Action1<RealmObject>() {
                        @Override
                        public void call(RealmObject realmObject) {

                        }
                    });

}

I would like to perform this query asynchronously then display the results on the UI.

Basically, whatever is been returned by response.body().getSquad() has an id matching a record already in the DB; and that is what am using in my equalTo method.

Based on the data received, I would like to update two columns on each of the record matching the IDs.

However, I am facing a few challenges on this:

  1. The Action1 in subscribe is returning a RealmObject instead of a PlayerObject
  2. How to proceed from here

Any guidance on this will be appreciated.

Thanks

Update

        if (response.isSuccessful()) {
        //asynchronously update the existing players records with my squad i.e is_selected
        for (MyGameEntrySquad squad : response.body().getSquad()) {

            realm.where(RealmPlayer.class).equalTo("id", squad.getPlayer().getId())
                    .findFirstAsync()
                    .<RealmPlayer>asObservable()
                    .filter(realmPlayer -> realmPlayer.isLoaded())
                    .subscribe(player -> {
                        realm.beginTransaction();
                        if (squad.getPlayer().getPosition().equals("GK")) {
                            player.setPlaygroundPosition("gk");
                            player.setIsSelected(true);
                        }

                        // pick the flex player
                        if (squad.isFlex()) {
                            player.setPlaygroundPosition("flex");
                            player.setIsSelected(true);
                        }

                        // pick the Goalie
                        if (squad.getPlayer().getPosition().equals("GK")) {
                            player.setPlaygroundPosition("gk");
                            player.setIsSelected(true);
                        }

                        // pick the DFs
                        if ((squad.getPlayer().getPosition().equals("DF")) && (!squad.isFlex())) {
                            int dfCounter = 1;
                            player.setPlaygroundPosition(String.format(Locale.ENGLISH, "df%d", dfCounter));
                            player.setIsSelected(true);
                            dfCounter++;
                        }

                        // pick the MFs
                        if ((squad.getPlayer().getPosition().equals("MF")) && (!squad.isFlex())) {
                            int mfCounter = 1;
                            player.setPlaygroundPosition(String.format(Locale.ENGLISH, "mf%d", mfCounter));
                            player.setIsSelected(true);
                            mfCounter++;
                        }

                        // pick the FWs
                        if ((squad.getPlayer().getPosition().equals("FW")) && (!squad.isFlex())) {
                            int fwCounter = 1;
                            player.setPlaygroundPosition(String.format(Locale.ENGLISH, "mf%d", fwCounter));
                            player.setIsSelected(true);
                            fwCounter++;
                        }

                        realm.copyToRealmOrUpdate(player);
                        realm.commitTransaction();
                        updateFieldPlayers();


                    });

        }

        hideProgressBar();

    }
realm.where(RealmPlayer.class).equalTo("id", squad.getPlayer().getId())
                        .findFirstAsync()
                        .<RealmPlayer>asObservable()
                        .subscribe(new Action1<RealmPlayer>() {
                            @Override
                            public void call(RealmPlayer player) {

                            }
                        });

You should do like that.

Btw, it's bad idea to do it in a cycle - check in method of RealmQuery.

for (MyGameEntrySquad squad : response.body().getSquad()) { // btw why is this not `Observable.from()`?
        subscription = realm.where(RealmPlayer.class).equalTo("id", squad.getPlayer().getId())
                .findFirstAsync()
                .asObservable()

This should not be on the UI thread. It should be on a background thread. On a background thread, you need to use synchronous query instead of async query.

Even on the UI thread, you'd still need to filter(RealmObject::isLoaded) because it's an asynchronous query, and in case of findFirstAsync() you need to filter for RealmObject::isValid as well.

For this case, you would not need asObservable() - this method is for observing a particular item and adding a RealmChangeListener to it . Considering this should be on a background thread with synchronous query, this would not be needed (non-looper background threads cannot be observed with RealmChangeListener s).

You should also unsubscribe from any subscription you create when necessary.

And yes, to obtain RealmPlayer in asObservable() , use .<RealmPlayer>asObservable() .

In short, you should put that logic on a background thread, and listen for changes on the UI thread. Background thread logic must be done with the synchronous API. You will not need findFirstAsync for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM