java - RxJava Multithreading with Realm - Realm access from incorrect thread -


background

i using realm within app. when data loaded undergoes intense processing therefore processing occurs on background thread.

the coding pattern in use unit of work pattern , realm exists within repository under datamanager. idea here each repository can have different database/file storage solution.

what have tried

below example of similar code have in foorespository class.

the idea here instance of realm obtained, used query realm objects of interest, return them , close realm instance. note synchronous , @ end copies objects realm unmanaged state.

public observable<list<foo>> getfoosbyid(list<string> fooids) {      realm realm = realm.getinstance(foorealmconfiguration);      realmquery<foo> findfoosbyidquery = realm.where(foo.class);      for(string id : fooids) {          findfoosbyidquery.equalto(foo.foo_id_field_name, id);         findfoosbyidquery.or();     }      return findfoosbyidquery             .findall()             .asobservable()             .doonunsubscribe(realm::close)             .filter(realmresults::isloaded)             .flatmap(foos -> observable.just(new arraylist<>(realm.copyfromrealm(foos)))); } 

this code later used in conjunction heavy processing code via rxjava:

datamanager.getfoosbyid(foo)             .flatmap(this::processthefoosinalongrunningprocess)             .subscribeon(schedulers.io()) //could schedulers.computation() etc             .subscribe(tilechannelsubscriber); 

after reading docs, belief above should work, not asynchronous , therefore not need looper thread. obtain instance of realm within same thread therefore not being passed between threads , neither objects.

the problem

when above executed get

realm access incorrect thread. realm objects can accessed on thread created.

this doesn't seem right. thing can think of pool of realm instances getting me existing instance created process using main thread.

kay so

return findfoosbyidquery         .findall()         .asobservable() 

this happens on ui thread, because that's you're calling initially

.subscribeon(schedulers.io()) 

aaaaand you're tinkering them on schedulers.io().

nope, that's not same thread!

as dislike approach of copying zero-copy database, current approach riddled issues due misuse of realmresults.asobservable(), here's spoiler code should be:

public observable<list<foo>> getfoosbyid(list<string> fooids) {    return observable.defer(() -> {        try(realm realm = realm.getinstance(foorealmconfiguration)) { //try-finally works            realmquery<foo> findfoosbyidquery = realm.where(foo.class);            for(string id : fooids) {                findfoosbyidquery.equalto(foofields.id, id);                findfoosbyidquery.or(); // please guarantee works?            }            realmresults<foo> results = findfoosbyidquery.findall();            return observable.just(realm.copyfromrealm(results));        }    }).subscribeon(schedulers.io()); } 

Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -