java - Obtaining reference to original Scheduler -
i have following rxjava observable
:
final class mapbitmapobservable { static observable<bitmap> create(@nonnull final mapview mapview) { return observable.create(new observable.onsubscribe<bitmap>() { @override public void call(final subscriber<? super bitmap> subscriber) { mapview.getmapasync(new onmapreadycallback() { @override public void onmapready(@nonnull final googlemap googlemap) { googlemap.snapshot(new googlemap.snapshotreadycallback() { @override public void onsnapshotready(@nullable final bitmap bitmap) { if (bitmap != null) { subscriber.onnext(bitmap); subscriber.oncompleted(); } else { subscriber.onerror(new mapsnapshotfailedexception()); } } }); } }); } }); } private mapbitmapobservable() { } }
the mapview
method getmapasync
must called on main thread avoid exception:
java.lang.illegalstateexception: getmapasync() must called on main thread @ com.google.android.gms.common.internal.zzx.zzcd(unknown source) @ com.google.android.gms.maps.mapview.getmapasync(unknown source) @ com.github.stkent.bugshaker.email.screenshot.maps.mapbitmapobservable$1.call(mapbitmapobservable.java:42) @ com.github.stkent.bugshaker.email.screenshot.maps.mapbitmapobservable$1.call(mapbitmapobservable.java:37) @ rx.observable.unsafesubscribe(observable.java:8098) ...
assume mapbitmapobservable
used part of observable
chain in previous , subsequent operations potentially long-running , should executed off main thread. simplified example this:
observable.just(activity) .flatmap(new func1<activity, observable<mapview>>() { @override public observable<bitmap> call(@nonnull final activity activity) { return expensivetocreateobservable.create(activity); } }) .flatmap(new func1<mapview, observable<bitmap>>() { @override public observable<bitmap> call(@nonnull final mapview mapview) { return mapbitmapobservable.create(mapview); } }) .flatmap(new func1<bitmap, observable<uri>>() { @override public observable<uri> call(@nonnull final bitmap bitmap) { return someotherexpensivetocreateobservable.create(bitmap); } }) .subscribeon(schedulers.io()) .subscribe();
(although should noted in actual application, chaining spread across several different methods). to:
- make sure
mapview.getmapasync
called on main thread; - allow second long-running operation execute on original scheduler, whatever may have been (
schedulers.io()
,schedulers.computation()
, etc.)
in mind, pseudocode achieve like:
observable.just(activity) .flatmap(new func1<activity, observable<mapview>>() { @override public observable<bitmap> call(@nonnull final activity activity) { return expensivetocreateobservable.create(activity); } }) .observeon(androidschedulers.mainthread()) // real, , resolves bullet 1. .flatmap(new func1<mapview, observable<bitmap>>() { @override public observable<bitmap> call(@nonnull final mapview mapview) { return mapbitmapobservable.create(mapview); } }) .observeon(/* way of referencing thread on subscribed, resolve bullet 2. */) .flatmap(new func1<bitmap, observable<uri>>() { @override public observable<uri> call(@nonnull final bitmap bitmap) { return someotherexpensivetocreateobservable.create(bitmap); } }) .subscribeon(schedulers.io()) // not want rely on knowledge of scheduler type used @ call-site. .subscribe();
is possible?
from observeon() documentation:
observeon, on other hand, affects thread observable use below operator appears. reason, may call observeon multiple times @ various points during chain of observable operators in order change on threads of operators operate.
so mentioned aaron he, keep reference scheduler using use on latter "observeon".
another approach use, remove both "observeon" function, , make sure view items being handled on ui thread activity.runonuithread. -
static observable<bitmap> create(@nonnull final activity activity,@nonnull final someobject someobject) { return observable.create(new observable.onsubscribe<pair<activity,someobject>>() { @override public void call(final subscriber<? super pair<activity,someobject>> subscriber) { activity.runonuithread(new runnable() { @override public void run() { someobject.dostuff(); } }); } }); }
Comments
Post a Comment