当我们没有指定它但仍指定subscribeOn的线程时,unsubscribeOn默认为什么线程? 我们是否需要指定我们想要取消订阅的线程,即使它与subscribeOn中使用的线程相同?
或者底部的两个片段是否为取消订阅做同样的事情?
选项1:
mSubscription.add(myAppProvider
.getSomeData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.unsubscribeOn(Schedulers.io())
.subscribe(data -> handleData(data),
throwable -> handleError(throwable)
));
选项2:
mSubscription.add(myAppProvider
.getSomeData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> handleData(data),
throwable -> handleError(throwable)
));
我确实看过Rx-Java docs,但他们只解释了subscribeOn,但没有解释unSubscribeOn
答案 0 :(得分:4)
如果没有downState
(并且没有upState
),您的取消订阅操作将在订阅开始的任何线程上发生。
使用subscribeOn
,您的取消订阅操作将在observeOn
指定的计划程序上进行。
使用subscribeOn
,您的取消订阅操作将在subscribeOn
指定的计划程序上进行(覆盖observeOn
指定的计划程序)。
这是sample。正如那里所建议的那样,当unsubscription本身涉及你想在其他线程上运行的长时间运行时,这很有用。
如果你运行他们的测试代码:
observeOn
你应该看到他们的预期输出:
subscribeOn
如果删除Observable<Object> source = Observable.using(
() -> {
System.out.println("Subscribed on " + Thread.currentThread().getId());
return Arrays.asList(1,2);
},
(ints) -> {
System.out.println("Producing on " + Thread.currentThread().getId());
return Observable.from(ints);
},
(ints) -> {
System.out.println("Unubscribed on " + Thread.currentThread().getId());
}
);
source
.unsubscribeOn(Schedulers.newThread())
.subscribe(System.out::println);
行,您会看到:
Subscribed on 1
Producing on 1
1
2
Unubscribed on 11
答案 1 :(得分:3)
这些片段有不同的行为。
通常,取消订阅会沿着运算符序列运行,并且可以由任何线程启动(只需从任何线程调用subscriber.unsubscribe()
)。如果没有unsubscribeOn
运算符,则取消订阅操作可能会在调用它的线程上完成其操作。 unsubscribeOn
可以更好地控制用于上游取消订阅的线程。
答案 2 :(得分:1)
什么线程是unsubscribeOn默认为我们没有指定它 但是仍然为subscribeOn指定线程?
默认情况下,subscribeOn / observeOn / unsubscribeOn都不是 设置,然后unsubscribeOn(以及其他人)默认为 当前主题。
如果我们为subscribeOn设置了一个线程而没有为 observeOn / unsubscribeOn,然后unsubscribeOn将使用相同的线程 在subscribeOn中指定。
如果我们同时调用subscribeOn和ObserveOn但不调用unsubscribeOn,那么 unsubscribeOn将使用observeOn中指定的线程。
如果所有三种方法(subscribeOn,observeOn和unsubscribeOn)都是 设置,然后unsubscribeOn将使用指定的线程 unsubscribeOn。实际上unsubscribeOn会在线程上发生 在unsubscribeOn方法中指定,无论以前的天气如何 方法是否设定。
我们是否需要指定要取消订阅的线程 即使它与使用的线程相同,也会发生 subscribeOn?
以下是我创建的一个示例,可用于在Android中测试上述内容。只需注释或更改线程,以测试各种结果。
public void testRxThreads() {
createThreadObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.unsubscribeOn(Schedulers.newThread())
.subscribe(printResult());
}
private Observable<String> createThreadObservable() {
return Observable.create(subscriber -> {
subscriber.add(new Subscription() {
@Override
public void unsubscribe() {
System.out.println("UnSubscribe on Thread: "
+ Thread.currentThread().getId() + " " + Thread.currentThread().getName());
// perform unsubscription
}
@Override
public boolean isUnsubscribed() {
return false;
}
});
subscriber.setProducer(n -> {
System.out.println("Producer thread: "
+ Thread.currentThread().getId() + " " + Thread.currentThread().getName());
});
subscriber.onNext("Item 1");
subscriber.onNext("Item 2");
subscriber.onCompleted();
});
}
private Action1<String> printResult() {
return result -> {
System.out.println("Subscriber thread: "
+ Thread.currentThread().getId() + " " + Thread.currentThread().getName());
System.out.println("Result: " + result);
};
}
这产生了以下结果
Producer thread: 556 RxIoScheduler-2
Subscriber thread: 1 main
Result: Item 1
Subscriber thread: 1 main
Result: Item 2
UnSubscribe on Thread: 557 RxNewThreadScheduler-1
注释掉或删除unsubscribeOn会产生以下结果。
Subscriber thread: 1 main
Result: Item 1
Subscriber thread: 1 main
Result: Item 2
UnSubscribe on Thread: 1 main
删除observeOn和unsubscribeOn调用会产生以下结果:
Producer thread: 563 RxIoScheduler-2
Subscriber thread: 563 RxIoScheduler-2
Result: Item 1
Subscriber thread: 563 RxIoScheduler-2
Result: Item 2
UnSubscribe on Thread: 563 RxIoScheduler-2
感谢drhr对事件的初步解释。这帮助我更多地研究并用上面的样本验证结果。