RXAndroid编写嵌套订阅的更好方法

时间:2018-10-08 22:29:46

标签: android android-bluetooth rx-android rxandroidble

我正在使用Android的RXBle库。为了从BLE外围设备(BLE设备)读取,我最终建立了许多订阅,彼此之间都是这样的:

    Disposable scanSubscription = null;

    public void startScan() {
        scanSubscription = rxBleClient
            .scanBleDevices(settings, filter)
            .take(1)
            .subscribe(
                scanResult -> connectDevice(scanResult.getBleDevice()),
                throwable -> {}
            );
    }

    public void connectDevice(RxBleDevice device) {
        device
            .establishConnection(false)
            .subscribe(
                connection -> requestMtu(connection),
                throwable -> {}
            );
    }

    public void requestMtu(final RxBleConnection connection) {
        connection
            .requestMtu(185)
            .subscribe(
                mtu -> readCharacteristic(connection),
                throwable -> {}
            );
    }

    public void readCharacteristic(final RxBleConnection connection) {
        /* this one eventually scanSubscription.dispose!!!!! */
    }

从本质上讲,我具有一系列对事物执行操作的功能,然后订阅生成的Single(我认为我使用的是正确的术语)

我的问题是,写这个的更好的方法是什么?

更重要的是,我从未取消订阅的嵌套订阅发生了什么?请注意,在第一个函数中,我调用了take(1)...最终,我只是处置了调用所有这些的顶级一次性容器。

1 个答案:

答案 0 :(得分:1)

不。那不是RX方式。我建议给this a quick read

tl; dr是您想要布置代码,使其像流一样流动。 Rx试图解决的事情之一就是消除嵌套的回调。这种“流”方法可以做到这一点。

现在您可以做些什么来使其变得更好。这是一种重写代码的方法,以使其成为流而不是一组嵌套的回调:

Disposable scanSubscription = null;

public void doThing() {
    scanSubscription = rxBleClient
        .scanBleDevices(settings, filter)
        .take(1)
        .map(scanResult -> scanResult.establishConnection(false))
        .map(connection -> connection.requestMtu(185))
        .map(mtu -> <do thing>)
        .subscribe(/* do things with final value */)
}

这是另一种方法:

Disposable scanSubscription = null;

public void doThing() {
    scanSubscription = rxBleClient
        .scanBleDevices(settings, filter)
        .take(1)
        .flatMap(scanResult -> scanResult.establishConnection(false))
        .flatMap(connection -> connection.requestMtu(185).map(result -> Pair(connection, result)))
        .flatMap(result -> {
            Connection c = result.first;
            Mtu mtu = result.second;
            //do thing
        })
        .subscribe(/* do things with final value */)
}