java - Realm access from incorrect thread Exception while a copy was sent using copyFromRealm -
when streaming copy of realm objects instead of realm reference , observing on schedulers.io thread, there crash famous exception message "realm access incorrect thread. realm objects can accessed in thread created."
shouldn't copy thread free? can produce 1 thread , process on different thread?
this how creating observable.
public observable<brand> getallbrands() { return realm.where(brand.class) .findall() .asobservable() .flatmap(observable::from) .map(brand -> realm.copyfromrealm(brand)); }
following how observe getallbrands().
observable<brand> brandobservable = datamanager.getallbrands(); brandobservable.observeon(androidschedulers.mainthread()) .subscribeon(schedulers.io()) .subscribe(new observer<brand>() { @override public void oncompleted() { log.d("reactive", "completed"); } @override public void onerror(throwable e) { log.d("reactive", e.getmessage()); } @override public void onnext(brand brand) { datasource.add(brand.getname()); myadapter.notifydatasetchanged(); } });
you subscribing on schedulers.io
while using realm instance ui thread:
realm.where(brand.class) .findall() .asobservable() .flatmap(observable::from) .map(brand -> realm.copyfromrealm(brand)) // realm instance on wrong thread .subscribeon(schedulers.io());
what after easy way move query across threads, still work-in-progress here: https://github.com/realm/realm-java/pull/1978. until can work around doing this:
public observable<brand> getallbrands(final realm realm) { return observable.create(new observable.onsubscribe<list<brand>>() { @override public void call(final subscriber<? super list<brand>> subscriber) { realm obsrealm = realm.getinstance(realm.getconfiguration()); final realmresults<brand> results = obsrealm.where(brand.class).findall(); final realmchangelistener listener = new realmchangelistener() { @override public void onchange() { subscriber.onnext(realm.copyfromrealm(results)); } }; results.addchangelistener(listener); subscriber.add(subscriptions.create(new action0() { @override public void call() { realm.removechangelistener(listener); realm.close(); } })); } }) .flatmap(observable::from); }
note realm changelisteners work on looper threads means need change worker thread h
handlerthread bgthread = new handlerthread("workerthread"); handler handler = new handler(bgthread.getlooper()); getallbrands(realm).subscribeon(handlerscheduler.from(handler));
Comments
Post a Comment