我有一个对象,它在随机的时间内生成不同的字符串,并且我需要征询该生成器的支持,以获取这些字符串并将其提供给ui(也许它将是不同活动中的多个订户)。 假设我得到以下代码:
发电机:
class Generator {
private var stringToGenerate = ""
var subject: BehaviorSubject<String> = BehaviorSubject.create<String>()
init {
//seems like these instructions are skipped
subject
.subscribeOn(AndroidSchedulers.mainThread())
.doOnNext { t -> Log.i("subject doOnNext", Thread.currentThread().name + " " + Thread.currentThread().id) }
.observeOn(AndroidSchedulers.mainThread())
.map { _ -> Log.i("subject map", Thread.currentThread().name + " " + Thread.currentThread().id) }
//imitation of async creating of strings in separate thread
timer("timerThread", false, 2000L, 2000L) {
stringToGenerate = System.currentTimeMillis().toString()
subject.onNext(stringToGenerate)
}
}
}
必须消耗生成的字符串的活动之一:
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
val wrongThreadObserver = object : Observer<String> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: String) {
Log.i("wrongThreadObserver", Thread.currentThread().name + " " + Thread.currentThread().id)
}
override fun onError(e: Throwable) {
}
}
val generator = Generator()
generator.subject.subscribe(wrongThreadObserver)
//for correct work illustration
val correctThreadObserver = object : Observer<String> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: String) {
Log.i("correctThreadObserver", Thread.currentThread().name + " " + Thread.currentThread().id)
}
override fun onError(e: Throwable) {
}
}
val mainThreadSubject = BehaviorSubject.create<String>()
mainThreadSubject
.doOnNext { obj -> Log.i("correctThread doOnNext", Thread.currentThread().name + " " + Thread.currentThread().id) }
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(correctThreadObserver)
mainThreadSubject.onNext("test thread")
val handler = Handler()
handler.postDelayed({ mainThreadSubject.onNext("test thread 2") }, 1000)
handler.postDelayed({ mainThreadSubject.onNext("test thread 3") }, 2000)
}
}
在这种情况下,仅在活动中创建的 correctThreadObserver 可以正常工作,但是 wrongThreadObserver 可以在计时器线程中工作,它似乎忽略了 subscribeOn,ObserveOn指令,在Generator中的doOnNext 上,无论这些指令在何处通过调用从生成器获取对象的方法-在初始化中,在计时器线程中,在活动中- wrongThreadObserver 仍在计时器线程中起作用。 所以日志是:
I / correctThread́doOnNext:主要2
I / correctThreadObserver:RxNewThreadScheduler-1 941
I / correctThread́doOnNext:主要2
I / correctThreadObserver:RxNewThreadScheduler-1 941
I / wrongThreadObserver:timerThread 937
I / correctThread́doOnNext:主要2
I / correctThreadObserver:RxNewThreadScheduler-1 941
I / wrongThreadObserver:timerThread 937
I / wrongThreadObserver:timerThread 937
I / wrongThreadObserver:timerThread 937
没有doOnNext
,也没有wrongThreadObserver
的主线程
我做错了什么?
答案 0 :(得分:0)
我找到以下解决方案:
我们必须订阅Observable
,而不是Subject
,因此我们必须使用方法observeOn()
的结果,而不是对象“主题”本身。
如果需要多次订阅,我们可以将observeOn
的结果缓存在单独的变量中:
//in Generator
.......
var observableInSeparateVar = subject.observeOn(AndroidSchedulers.mainThread())
.......
//in TestActivity
.......
generator.observableInSeparateVar.subscribe(wrongThreadObserver)
.......
我们也可以致电observeOn()
进行主题预订,然后进行订阅:
//in TestActivity
.......
generator.subject
.observeOn(AndroidSchedulers.mainThread())
.subscribe(wrongThreadObserver)