它更像是一般问题,而不是特定问题。
基本上我正在开发一个与Ble Peripheral Device通信的Android应用程序。 我使用RxAndroidBle库处理Ble通信。至于一般模式,我决定尝试使用Mosby MVI 那并不重要。
到目前为止,我所做的是创建了BluetoothManager类,负责执行所有操作 在Ble设备上。这个类是Singleton(我知道它不推荐在Android上使用),我使用Dagger确定了它的范围, 这只会注入那些应该执行Ble通信的交互者。 此类返回带有一些POJO的Observable,它们在交互器中转换为ViewStates,然后向上移动到UI。 订阅位于Mosby MVI模式后的演示者中。
基本上,我要将此Ble Device视为常规数据源,与某些改装服务或任何数据库相同。 只要我执行原子操作(如编写和读取某些特征),那就完全没问了。
问题是当我需要启动某种可能需要花费很多时间的同步时,应该在后台完成, 不应该绑定到UI,但是在某些屏幕上,用户应该能够看到进度。 在这里,我开始考虑使用Android服务并将所有Ble Communication逻辑放在那里, 但是在我看来,使用Android服务打破了逻辑分离的任何尝试,我无法找到适合它的好方法。
然而,第三个选项是提供同步服务并保留BluetoothManager以进行与UI绑定的原子操作 我觉得它很乱,我很高兴将所有Ble的东西放在一个地方。
我知道它很长但是这一切都归结为一个问题 - >在Android上与Ble设备通信时,最好的模式是什么? 保持层分离并使其尽可能独立。 我找不到任何有关处理的好文章,如果有任何它们已经过时,不使用Rx方法。 如果它太通用了,我可以指定更多细节,但我更多地寻找建筑建议而不是代码片段。
答案 0 :(得分:0)
这样的事情怎么样:
而不是直接在演示者中订阅蓝牙,引入课程BleRepository
然后BleRepository
提供了一个metod 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。演示者不知道实际的蓝牙连接。那么你接下来要做的就是将实际的蓝牙连接转移到Android服务中,让我们称之为BluetoothService
。然后BluetoothService
得到连接,无论何时运行同步或连接接收/发送的任何其他内容,它都会将该数据发送回服务订阅的BleRepository.getDataObservable()
。您只需确保Service和Presenter“共享”相同的BleRepository
实例。即使用匕首注入相同的实例或使它成为单身......任何最适合你的。
根据您的用例,您还可以使BluetoothService
订阅意识到在RxJavas onSubscribe中启动Android服务并在取消订阅/ onTerminal上停止服务。但听起来你的用例略有不同,即使Presenter / view已被破坏,蓝牙仍然连接,对吧?无论如何,我们的想法是使用服务(服务,如果它对您的问题有意义),但它们都以某种方式将数据推送到BleRepository,然后将数据传递给Presenter。