Архитектура клиентского приложения Android Ble

Это скорее общий вопрос, а не конкретный.

В основном я разрабатываю приложение для Android, которое взаимодействует с периферийным устройством Ble. Я управляю связью Ble с помощью библиотеки RxAndroidBle. Что касается общей схемы, я решил попробовать Mosby MVI, но это не так важно.

До сих пор я создал класс BluetoothManager, который отвечает за выполнение всех операций на устройстве Ble. Этот класс является Singleton (я знаю, что это не рекомендуется для Android), и я ограничил его с помощью Dagger, что он вводится только тем интеракторам, которые должны выполнять некоторую связь Ble. Этот класс возвращает Observables с некоторыми POJO, которые преобразуются в ViewStates в интеракторе и перемещаются выше в пользовательский интерфейс. Подписки ведутся по образцу Mosby MVI.

В основном благодаря тому, что я рассматриваю это устройство Ble как обычный источник данных, так же, как некоторую модифицированную службу или любую базу данных. И это было совершенно нормально, пока я выполнял атомарные операции, такие как запись и чтение отдельных характеристик.

Проблема в том, что когда мне нужно запустить какую-то синхронизацию, которая может занять довольно много времени, должна выполняться в фоновом режиме, НЕ должна быть связана с пользовательским интерфейсом, однако на некоторых экранах пользователь должен видеть прогресс. Здесь я начал задумываться об использовании Сервиса Android и размещении всей логики Ble Communication, однако, по моему мнению, использование сервиса Android ломает любые попытки логического разделения, и я не мог найти хороший способ приспособить его там.

Третий вариант - иметь сервис для синхронизации и сохранения BluetoothManager для элементарных операций, привязанных к пользовательскому интерфейсу, однако я думаю, что это грязно, и было бы неплохо, чтобы все вещи Ble были в одном месте.

Я знаю, что это долго, но все это сводится к одному вопросу -> каков будет наилучший шаблон для общения при использовании устройства Ble на Android, чтобы сохранить разделение слоев и сохранить его как можно более независимым. Я не смог найти хороших статей о том, как их обработать, если они есть, они устарели, не используя подход Rx. Если это слишком общий характер, я могу указать некоторые дополнительные детали, но я больше ищу архитектурный совет, а не фрагменты кода.

1 ответ

Что-то вроде этого: вместо того, чтобы напрямую подписываться на ведущий на bluetooth, введите класс BleRepository

затем BleRepository предоставляет метод Observable<Foo> (Foo - это те данные, которые должен видеть ваш Presenter / UI) и операции для выполнения таких вещей, как doA(), Что-то вроде этого:

interface BleRepository {


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

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

}

Так что ведущий подписывается на BleRepository вместо подключения к Bluetooth напрямую.

Так что теперь, когда вы выполняете "операцию записи", вы просто выполняете ее, но всегда читаете новые данные из getDataObservable() даже если сама операция записи возвращает новые данные, чтение данных всегда проходит getDataObservable(),

Так BleRepository это просто публичный API, используемый вашим докладчиком. Ведущий не знает о фактическом соединении Bluetooth. Итак, что вы можете сделать дальше, это переместить фактическое соединение Bluetooth в службу Android, давайте позвоним BluetoothService, затем BluetoothService get is connected и всякий раз, когда выполняется синхронизация или что-либо еще, что ваше соединение получает / отправляет, оно отправляет эти данные обратно BleRepository.getDataObservable() который подписан на услугу. Вы просто должны убедиться, что и Сервис, и Презентатор "делятся" одним и тем же BleRepository пример. то есть используйте кинжал для инъекции того же самого экземпляра или сделайте его одиночным... что бы ни работало лучше для вас.

В зависимости от вашего использования вы также можете сделать BluetoothService подписка осведомлена, как запустить службу Android в RxJavas onSubscribe и остановить службу в отписаться / onTerminal. Но похоже, что ваш сценарий использования немного отличается, так что Bluetooth все еще подключен, даже если Presenter / view был уничтожен, верно? Как бы то ни было, идея состоит в том, чтобы использовать Service (Services, если это имеет смысл для вашей проблемы), но все они каким-то образом помещают данные в BleRepository, который затем доставляет данные в Presenter.

Другие вопросы по тегам