Search code examples
androiddatabaseasynchronousrealmgoogle-maps-android-api-2

Realm Android: Async Transaction affect UI thread


I'm currently using realm to query RealmObjects to show them on a GoogleMap. I am performing the read and getting the RealmResults but I can't find a way to put the markers on the map from the UI thread. I'd prefer to do this with an async call because it causes ~150ms of lag on the UI thread.

public void loadLocations(final GoogleMap googleMap) {
        try {

        realm.executeTransactionAsync(new Realm.Transaction() {

            @Override
            public void execute(Realm realm) {
                RealmResults<LocationObject> locations = realm.where(LocationObject.class).findAll();
                for (LocationObject location: locations ) {
                        googleMap.addMarker(new MarkerOptions()
                                .position(new LatLng(location.lat, location.long))
                }
            }
        });
}

How can I later access the RealmResults on the UI thread? Realm mentions that RealmObjects are thread confined


Solution

  • You can try using RealmChangeListener. The Realm docs illustrate this very clearly using the puppies example.

    RealmResults<LocationObject> locations;
    
    //...
        locations = realm.where(LocationObject.class).findAllAsync();
    
        locations.addChangeListener(new RealmChangeListener<Person>() {
            @Override
            public void onChange(RealmResults<LocationObject> locations) {
                googleMap.clear();
                for (LocationObject location: locations) {
                    googleMap.addMarker(new MarkerOptions()
                                .position(new LatLng(location.lat, location.long));
                }
            }
        }
    

    The code above basically do a query asynchronously to the Realm database and the addChangeListener registers a callback method to be invoked when the query is done and will be invoked in future query calls as well (Refer to the realm docs for more info on this).

    So, I would suggest running the code above in an onStart or onResume method and don't forget to remove the change listener on onStop or onPause method, like so:

    locations.removeChangeListeners();
    

    Lastly, don't forget to close realm. Hope it helps! Don't hesitate to ask if anything is unclear.