0

it's more a general question rather than a specific one.

Basically I'm developing an Android app which communicates with Ble Peripheral Device. I handle Ble communication using RxAndroidBle library. As for the general pattern, I decided to try Mosby MVI, however that's not that important.

What I did so far is I created BluetoothManager class which is responsible for performing all the operations on the Ble Device. This class is a Singleton (I know it's not recommended on Android) and I scoped it using Dagger, that this is injected only to those interactors that should perform some Ble communication. This class returns Observables with some POJOs, which are transformed to ViewStates in interactor and than moved higher to the UI. Subscriptions are in the presenters following Mosby MVI pattern.

Basically thanks to that I treat this Ble Device as a regular data source, same as some retrofit service or any db. And that was totally fine as long as I was performing atomic operations like writing and reading some single characteristics.

The problem is when I need to fire up some kind of a synchronization that may take quite a lot of time, should be done on background, should NOT be bound to UI, however on some screens user should be able to see the progress. Here I started to think about using Android Service and putting all the Ble Communication logic there, however in my opinion using Android service breaks any attempts of logic separation and I couldn't find a good way to fit it there.

Third option was having a service for synchronization and preserving BluetoothManager for atomic operations bounded to UI, however I think it's messy and I would be nice to have all the Ble stuff in one place.

I know it's long but it all goes to one question -> what would be the best pattern to follow when communicating with Ble device on Android to preserve layers separation and keeping it as independent as possible. I could not find any good articles about handling that, if there are any they are quite out dated, not using Rx approach. If it's too generic, I can specify some more details, but I'm looking more for an architectural advice rather than code snippets.

Jogosb
  • 155
  • 1
  • 12

1 Answers1

0

What about something like this: instead of subscribing in presenter to bluetooth directly, introduce a class BleRepository

Then BleRepository provides a metod Observable<Foo> (Foo is whatever data your Presenter / UI should see) and operations to execute stuff like doA(). Something like this:

interface BleRepository {


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

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

}

So the Presenter subscribes to BleRepository instead to bluetooth connection directly.

So now whenever you do a "write operation" you just execute it but you always read new data from getDataObservable() even if the write operation itself returns new data, reading data always goes through getDataObservable().

So BleRepository is basically just a public API your presenter uses. The Presenter doesn't know about the actual Bluetooth connection. So what you can do next is moving the actual bluetooth connection into an android service, lets call it BluetoothService. Then BluetoothService get's connected and whenever the sync runs or whatever else your connection receives / sends, it emits that data back to BleRepository.getDataObservable() which is subscribed by the service. You just have to ensure that both Service and Presenter "share" the same BleRepository instance. i.e. use dagger to inject the same instance or make it a singleton ... whatever works best for you.

Depending on your usecase you can also make the BluetoothService subscription aware like start the android service in RxJavas onSubscribe and stop the service in on unsubscribe / onTerminal. But it sounds like your usecase is slightly different so that Bluetooth is still connected even if Presenter / view has been destoryed, right? Whatever, the idea is use Service (Services if it makes sense for your proble) but they all somehow push the data into BleRepository that then delivers the data to the Presenter.

sockeqwe
  • 15,574
  • 24
  • 88
  • 144
  • Thanks for a response! I was trying to fit Your previous response from [here](https://stackoverflow.com/questions/43042785/android-mosby-mvi-bind-to-service-in-presenter?rq=1) but I found it quite difficult. What would You use as this DataObservable? Some BehaviourSubject and I would fire onNext on it whenever i get some value from device? And also what would You say about multiple dataObservables as I can read/write quite a lot to the device and not all of those can be easily mapped to one type of an object. – Jogosb Aug 16 '17 at 12:14
  • This answer was on a bound service which you certainly don't need! Sure if that makes it easier for you than multiple data observables may makes sense. I usually prefer just one, but it depends on the data and I have no clue what you are exactly doing. Take a look at PublishRelay (instead of BehaviorSubject) – sockeqwe Aug 16 '17 at 20:03