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

标签 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)...最终,我只是处理了调用所有这些的顶级一次性函数。

最佳答案

没有。那不是 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 */)
}

关于android - RXAndroid 编写嵌套订阅的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52710904/

相关文章:

javascript - 如何让 native WebSockets 在 Android 4.03 及更高版本中工作?

android - 搜索 View 关闭图标显示为禁用而不是白色

android - 蓝牙 : Transferring call from Source to sink?

android - 如何在 retrofit 2 + rx-android 上注册全局错误转换器?

android - 如何让两个单独的按钮在一个 Activity 中做两件不同的事情?

android - 身份验证请求失败 PayPal Android SDK 示例

android - 蓝牙不发送文件到其他设备

java - Android:BluetoothSocket 连接抛出 IOException

observable - takeFirst 方法的替代方法是什么

android - RxAndroid,在 onDestroy() Activity 中停止计时器/observable.interval