我正在处理这个问题。
我试图以同步方式调用RxJava,但这样做会导致阻塞主线程。
这是我的代码
@Override
public Single<SettingsBundle> getSettings() {
SettingsBundle settingsModel = mSettingsManager.getSettings();
return Single.just(settingsModel).map(mSettingsMapper);
}
这是我的同步电话
@Override
public SettingsBundle getSettingsSync() {
return getSettings().blockingGet();
}
当调用getSettingsSync
主线程被阻止时,但有时它工作正常,更有问题。
我尝试了类似的东西
@Override
public SettingsBundle getSettingsSync() {
return getSettings()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.blockingGet();
}
但它仍然被阻止。
我做错了什么,我将不胜感激任何帮助。
感谢。
答案 0 :(得分:6)
<强> TL; TR 强>
永远不要将observeOn(AndroidSchedulers.mainThread())
与blockingGet()
长版
输出:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val result =
Single.just("Hello")
.subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
.map {
println("1. blockingGet `$it` thread: ${Thread.currentThread()}")
return@map it
}
.blockingGet()
println("2. blockingGet `$result` thread: ${Thread.currentThread()}")
}
}
是
1. blockingGet `Hello` thread: Thread[RxCachedThreadScheduler-1,5,main]
2. blockingGet `Hello` thread: Thread[main,5,main]
正如您所见,结果是在主线程(第2行)上生成的,map函数是在RxCachedThreadScheduler线程中执行的。
如果行.observeOn(AndroidSchedulers.mainThread())
已取消注释,则blockingGet()
永远不会返回,而且所有内容都会被停用。
答案 1 :(得分:3)
.observeOn(AndroidSchedulers.mainThread())
.blockingGet();
此特定运营商组合中存在问题。 AndroidSchedulers安排代码在主线程上运行,但blockingGet()
阻止更多代码在该线程上执行。简单地说AndroidSchedulers
和RxJava
的阻塞运算符不能很好地协同工作。
由于android调度程序可能用于构造observable,这意味着无论你尝试做什么,主线程上任何blocking*
运算符的使用都将容易出现死锁。
答案 2 :(得分:0)
如果您确实需要在主线程上运行一个函数并且还需要使其同步,那么您可以执行以下操作:
如果这是主线程(Looper.myLooper() == Looper.getMainLooper()
),请运行func()
如果不在主线程上,则可以使用observeOn(AndroidSchedulers.mainThread())
和blockingGet()