2017-08-16 105 views
0

这是一个更普遍的问题,而不是一个特定的问题。Android Ble客户端应用程序体系结构

基本上我正在开发一个Android应用程序,它与Ble Peripheral Device进行通信。 我使用RxAndroidBle库处理Ble通信。至于一般模式,我决定尝试莫斯比MVI,但是 这并不重要。

我到目前为止所做的是我创建的BluetoothManager类,它负责执行Ble Device上的所有操作 。这个类是一个Singleton(我知道它不推荐在Android上使用),并且我使用Dagger作为范围, 这只被注入到那些应该执行一些Ble通信的交互器中。 此类返回具有一些POJO的Observables,它们在交互器中转换为ViewStates,并向UI中移动更高。 订阅在Mosby MVI模式下的演示者中。

基本上感谢我把这个Ble设备作为一个常规的数据源,和一些改造服务或者任何db一样。 只要我正在进行像写作和阅读某些单一特征的原子操作,那就完全没问题。

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

第三种选择是同步和保留BluetoothManager用于界面到UI的原子操作的服务,但是 我认为这很麻烦,我很高兴在所有Ble的东西在一个地方。

我知道这是很长,但是这一切都为一个问题 - >什么是Android上 BLE装置通信保持层分离并保持尽可能独立时应遵循的最佳模式。 我找不到任何有关处理的好文章,如果有任何文章过时,请不要使用Rx方法。 如果它太泛型,我可以指定一些更多的细节,但我更多的是寻找建筑建议,而不是代码片段。

回答

0

什么是这样的: ,而不是在主持人订阅直接蓝牙,引进一类BleRepository

然后BleRepository提供梅托德Observable<Foo>(foo是任何数据的演示/ UI应该看到)和操作执行例如doA()。事情是这样的:

interface BleRepository { 


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

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

} 

所以演示订阅BleRepository,而不是直接的蓝牙连接。

所以,现在每当你做一个“写操作”你只是执行它,但你总是从getDataObservable()读取新的数据,即使写操作本身返回的新数据,读取数据总是通过getDataObservable()去。

因此BleRepository基本上只是您演示者使用的公共API。演示者不知道实际的蓝牙连接。因此,接下来你可以做的是将实际的蓝牙连接转移到android服务中,我们称之为BluetoothService。然后BluetoothService get的连接,并且每当同步运行或其他任何您的连接收到/发送时,它都会将该数据发送回由服务订阅的BleRepository.getDataObservable()。您只需确保Service和Presenter“共享”相同的BleRepository实例。即使用匕首注入相同的实例或使其成为一个单身...任何最适合您的工具。

根据您的用例,您还可以使BluetoothService订阅知道,例如在RxJavas onSubscribe上启动android服务,并停止取消订阅/ onTerminal上的服务。但听起来你的用例略有不同,即使演示者/视图已被删除,蓝牙仍然连接,对吗?无论如何,这个想法是使用Service(服务,如果它对您的问题有意义),但它们都以某种方式将数据推送到BleRepository,然后将数据传递给Presenter。

+0

感谢您的回应!我试图去适应你以前的回应[这里](https://stackoverflow.com/questions/43042785/android-mosby-mvi-bind-to-service-in-presenter?rq=1),但我发现它相当难。你将使用什么作为这个DataObservable?一些BehaviourSubject和我会每当我从设备获得一些价值时onNext上它?还有,你会怎么说多个dataObservables,因为我可以读/写很多设备,并不是所有这些都可以很容易地映射到一种类型的对象。 – Jogosb

+0

这个答案是在你肯定不需要的绑定服务上! 当然,如果这使得它更容易比多个数据可观察到可能是有意义的。我通常只喜欢一个,但这取决于数据,我不知道你到底在做什么。看看PublishRelay(而不是BehaviorSubject) – sockeqwe