I am dealing with the problem.
I am trying to call RxJava in the sync manner, however doing that results in blocking the Main thread.
Here is my code
@Override
public Single<SettingsBundle> getSettings() {
SettingsBundle settingsModel = mSettingsManager.getSettings();
return Single.just(settingsModel).map(mSettingsMapper);
}
And here is my sync call
@Override
public SettingsBundle getSettingsSync() {
return getSettings().blockingGet();
}
When calling the getSettingsSync
the Main thread is blocked, however sometimes it works fine, what is more problematic.
I have tried something like that
@Override
public SettingsBundle getSettingsSync() {
return getSettings()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.blockingGet();
}
But it stills remains blocked.
What I am doing wrong, I would be grateful for any help.
Thanks.
TL;TR
never use
observeOn(AndroidSchedulers.mainThread())
withblockingGet()
Long version
The output for:
is
As you can see result was generated on main thread (line 2), the map function was execute in the RxCachedThreadScheduler thread.
With the line
.observeOn(AndroidSchedulers.mainThread())
decommented theblockingGet()
never return and all is stucked.The problem exists in this specific combination of operators. AndroidSchedulers schedules code to run on the main thread, however the
blockingGet()
stops more code from executing on that thread. Simply putAndroidSchedulers
and the blocking operators ofRxJava
do not work well together.Since the android scheduler might be used in the construction of the observable this means any use of the
blocking*
operators on the main thread will be prone to deadlocks regardless of what you try to do.If you really need a function to run on the main thread and also need it to be synchronous, then you could do something like this:
If this is the main thread (
Looper.myLooper() == Looper.getMainLooper()
), then run func()If not on the main thread, then you can use the combination of
observeOn(AndroidSchedulers.mainThread())
withblockingGet()