0

这更像是一个笼统的问题,而不是一个具体的问题。

基本上我正在开发一个与 Ble 外围设备通信的 Android 应用程序。我使用RxAndroidBle库处理 Ble 通信。至于一般模式,我决定尝试 Mosby MVI,但这并不重要。

到目前为止,我创建了 BluetoothManager 类,该类负责在 Ble 设备上执行所有操作。这个类是一个 Singleton(我知道它在 Android 上不推荐),我使用 Dagger 对其进行了限定,它只注入到那些应该执行一些 Ble 通信的交互器。此类返回带有一些 POJO 的 Observable,这些 POJO 在交互器中转换为 ViewState,然后移到 UI 的更高位置。按照Mosby MVI模式在演示者中订阅。

基本上感谢我将此 Ble 设备视为常规数据源,与某些改造服务或任何数据库相同。只要我执行原子操作,比如写入和读取一些单一特征,那完全没问题。

问题是当我需要启动某种可能需要很长时间的同步时,应该在后台完成,不应该绑定到 UI,但是在某些屏幕上用户应该能够看到进度。在这里,我开始考虑使用 Android 服务并将所有 Ble 通信逻辑放在那里,但是在我看来,使用 Android 服务会破坏任何逻辑分离的尝试,我找不到适合它的好方法。

第三种选择是提供同步服务并为绑定到 UI 的原子操作保留 BluetoothManager,但是我认为这很混乱,如果将所有 Ble 东西放在一个地方,我会很高兴。

我知道这很长,但一切都归结为一个问题 -> 在 Android 上与 Ble 设备通信以保持层分离并使其尽可能独立时,最好遵循的模式是什么。我找不到任何关于处理它的好文章,如果有的话,它们已经过时了,而不是使用 Rx 方法。如果它太笼统,我可以指定更多细节,但我更多的是寻找架构建议而不是代码片段。

4

1 回答 1

0

像这样的东西怎么样:不是直接在演示者中订阅蓝牙,而是引入一个类BleRepository

然后BleRepository提供一个方法Observable<Foo>(Foo 是您的 Presenter / UI 应该看到的任何数据)和执行诸如doA(). 像这样的东西:

interface BleRepository {


   // Read Data
   Observable<Foo> getDataObservable();

   // Write Data operations
   Completable doA();
   Completable doB(); 

}

因此,Presenter 直接订阅了BleRepository蓝牙连接。

因此,现在每当您执行“写入操作”时,您只需执行它,但您总是从中读取新数据,getDataObservable()即使写入操作本身返回新数据,读取数据也总是通过getDataObservable().

所以BleRepository基本上只是您的演示者使用的公共 API。演示者不知道实际的蓝牙连接。所以接下来你可以做的就是将实际的蓝牙连接移动到一个安卓服务中,让我们调用它BluetoothService。然后得到连接,每当同步运行或您的连接接收/发送任何其他内容时,它都会将服务订阅的BluetoothService数据发送回。BleRepository.getDataObservable()您只需确保 Service 和 Presenter “共享”同一个BleRepository实例。即使用匕首注入相同的实例或使其成为单例......任何最适合你的东西。

根据您的用例,您还可以使BluetoothService订阅感知,例如在 RxJavas onSubscribe 中启动 android 服务并在取消订阅 / onTerminal 时停止服务。但听起来您的用例略有不同,因此即使 Presenter / view 已被破坏,蓝牙仍处于连接状态,对吧?不管怎样,这个想法是使用服务(如果对您的问题有意义,则服务),但它们都以某种方式将数据推送到 BleRepository,然后将数据传递给 Presenter。

于 2017-08-16T12:01:43.610 回答