Reputation: 62519
Given this simple Observer and subscriber combo which simply observes a file IO and then updates in the subscriber based on the value:
Observable.just(preferences.getBoolean(C"vibrate", false))
.subscribeOn(Schedulers.io())//observe on new thread
.observeOn(AndroidSchedulers.mainThread()) //subscribe(listen) on main thread
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean shouldVibrate) {
if (shouldVibrate)
Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
}
});
My question is, does the observer block until write is complete ? Even though i specify another thread (IO thread) does this observer still block once called by the subscriber ?
Upvotes: 1
Views: 760
Reputation: 11515
Your Observer
won't block as your operation be done BEFORE you subscribe to your Observer
(so, it will just emit your value)
Regarding your code (java 8 style for simplicity) :
Observable.just(preferences.getBoolean("vibrate", false))
.subscribeOn(Schedulers.io())//observe on new thread
.observeOn(AndroidSchedulers.mainThread())
.subscribe(shouldVibrate) -> {
if (shouldVibrate) {
Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
}
});
You can extract the call as a variable preferences.getBoolean(C"vibrate", false)
:
Boolean vibrate = preferences.getBoolean("vibrate", false);
Observable.just(vibrate)
.subscribeOn(Schedulers.io())//observe on new thread
.observeOn(AndroidSchedulers.mainThread())
.subscribe(shouldVibrate) -> {
if (shouldVibrate) {
Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
}
});
As you can see, the vibrate
will be computed before and then the main thread will be blocked.
You should write a "lazy" call to your method using Observable.create
method
Observable.create(sub -> {
Boolean vibrate = preferences.getBoolean("vibrate", false);
sub.onNext(vibrate);
sub.onCompleted();
})
.subscribeOn(Schedulers.io())//observe on new thread
.observeOn(AndroidSchedulers.mainThread())
.subscribe(shouldVibrate) -> {
if (shouldVibrate) {
Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
}
});
With this code, the Boolean vibrate = preferences.getBoolean("vibrate", false);
will be called only when you'll subscribe to your Observer
.
(regarding to your if, in your subscriber, you can change it with a filter
)
Observable.create(sub -> {
Boolean vibrate = preferences.getBoolean("vibrate", false);
sub.onNext(vibrate);
sub.onCompleted();
})
.filter((value) -> value)
.subscribeOn(Schedulers.io())//observe on new thread
.observeOn(AndroidSchedulers.mainThread())
.subscribe(shouldVibrate) -> {
Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
});
Upvotes: 1