Android 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()

我感兴趣的是flatMap如何控制其“子”线程,例如,以下代码运行良好:

 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();