Android flatMap如何深入工作?
我感兴趣的是flatMap如何控制其“子”线程,例如,以下代码运行良好:Android flatMap如何深入工作?,android,rx-java,rx-java2,rx-android,Android,Rx Java,Rx Java2,Rx Android,我感兴趣的是flatMap如何控制其“子”线程,例如,以下代码运行良好: private Flowable<PlcDataPackage> createIntervalPlcFlowable() { return Flowable.interval(1, TimeUnit.SECONDS, Schedulers.computation()) .onBackpressureLatest() .parallel()
private Flowable<PlcDataPackage> createIntervalPlcFlowable() {
return Flowable.interval(1, TimeUnit.SECONDS, Schedulers.computation())
.onBackpressureLatest()
.parallel()
.runOn(Schedulers.computation())
.flatMap((Function<Long, Publisher<PlcDataPackage>>) aLong -> mDataPackageFlowable)
.sequential();
}
用例:
public class GetPlcUpdatesChanelUseCase extends UseCase<PlcDto, Object> {
private final PlcRepository mPlcRepository;
public GetPlcUpdatesChanelUseCase(PlcRepository plcRepository) {
mPlcRepository = plcRepository;
}
@Override
public Flowable<PlcDto> buildFlowable(Optional<Object> optional) {
return mPlcRepository.getUpdatesChannel();
}
@Override
public boolean isParamsRequired() {
return false;
}
}
据我所知,mDataPackageFlowable只创建一次,然后执行,每次为其子线程创建新的“线程”,执行128次后,它只会阻止所有后续执行
因此,有三个主要问题:
1) flatMap是否控制子线程
2) 为什么它要在一个新线程上执行每个新的“请求”
3) 在什么情况下,我们可以失去对子线程的控制
DISCLAMER:英语是我的第二语言,如果有什么不清楚的地方,请问我,我会尽力补充说明
private-Flowable-createIntervalPlcFlowable(){
返回可流动的.interval(1,TimeUnit.SECONDS,Schedulers.computation())
.onBackpressureLatest()
.parallel()
.runOn(Schedulers.computation())
.sequental()
此组合不起作用,它实际上删除了128倍的flatMap调用限制,但不会清除导致内存泄漏和OOM异常的旧innersubscription。请改用某种类型的映射。需要订阅才能使观察者链正常工作。使用
interval()时
要生成数据,您需要提供一个“热”可观察对象,它自己会发出值。“冷”可观察对象只有在订阅发生时才会发出值
128是在暂停之前由flatMap()
缓冲的条目数。如果有订阅,则flatMap()
将向下游发出内部可观察对象生成的值,并且不会暂停
根据javadoc的说法,flatMap()
本身不会在特定的调度程序上运行。这意味着它不会在特定的线程上操纵其订阅。如果您想控制由flatMap()
调用的可观察线程中正在进行的工作,那么您可以使用显式调度:
observable
.flatMap( value -> fun(value).subscribeOn( myScheduler ) )
.subscribe();
例如,myScheduler
可能是一个Schedulers.io()
,它可以在需要时创建线程。或者,它可以是一个执行器,您可以提供固定数量的线程。我经常使用执行器,它只有一个、两个或48个线程分配给它来控制平面图()的扇出
您还可以向flatMap()
提供一个parallelism参数,该参数告诉它将保持的最大订阅数。当flatMap()
达到最大值时,它将缓冲请求,直到订阅完成为止
parallel()
操作符也做了类似的事情,但是它将传入的事件分离出来,在不同的线程上发出它们
总是有可能失去对线程的控制。当您使用RxJava操作符时,请阅读它的文档。有两个方面您需要了解。第一个方面是该操作符所使用的调度程序。如果它说它不在特定调度程序上操作,则它不会直接影响线程的选择或如何执行使用ds。如果它声明它使用特定的调度程序,则您需要了解该调度程序的工作原理;始终会有另一个版本的运算符,允许您提供自己选择的调度程序
您必须了解的第二个方面是背压。您需要了解背压的含义及其应用方式。当您跨过线程边界时,这一点尤其重要,例如使用observeOn()
或subscribeOn()
我尝试了你的建议,但它不起作用。我曾尝试显式地将subscribeOn添加到flatMap,但它在128次发射后停止,我唯一可以修复它的方法是并行和顺序运算符。我仍然不明白为什么flatMap会失去对其“子”线程的控制。即使使用subscribeOn(myScheduler)我读过这篇文章:它确实有帮助,但还有一些问题,如果你不订阅observer链,那么它将停止。句号。我订阅了这个链一次,然后我收到所有128个值,链冻结。我的意思是我的应用程序没有订阅这个Flowable的128+次,它很热,所以看起来一切都很好应该是st。subscribeOn()
与subscribe()
public class GetPlcUpdatesChanelUseCase extends UseCase<PlcDto, Object> {
private final PlcRepository mPlcRepository;
public GetPlcUpdatesChanelUseCase(PlcRepository plcRepository) {
mPlcRepository = plcRepository;
}
@Override
public Flowable<PlcDto> buildFlowable(Optional<Object> optional) {
return mPlcRepository.getUpdatesChannel();
}
@Override
public boolean isParamsRequired() {
return false;
}
}
@Override
public Flowable<PlcDto> getUpdatesChannel() {
return mPlcCore.getPlcConnectableFlowable()
.map(mPlcInfoTopPlcDtoTransformer::transform);
}
public ConnectableFlowable<PlcDataPackage> getPlcConnectableFlowable() {
return mConnectableFlowable;
}
mConnectableFlowable = createConnectablePlcFlowable();
mConnectableFlowable.connect();
private Flowable<PlcDataPackage> createIntervalPlcFlowable() {
return Flowable.interval(1, TimeUnit.SECONDS, Schedulers.computation())
.onBackpressureLatest()
.parallel()
.runOn(Schedulers.computation())
.sequental()
observable
.flatMap( value -> fun(value).subscribeOn( myScheduler ) )
.subscribe();