Я много думал о том, где разместить Android Services в новой рекомендованной архитектурой Android. Я придумал много возможных решений, но я не могу решить, какой из них - лучший подход.
Я провел много исследований, и я не мог найти никакого полезного руководства или учебника. Единственный намек, который я нашел о том, где разместить Сервис в моей архитектуре приложения, - это один, из средней страницы @JoseAlcerreca
В идеале ViewModels не должен знать ничего о Android. Это улучшает тестируемость, безопасность утечек и модульность. Общее правило заключается в том, чтобы убедиться, что нет андроида. * Import в ваших ViewModels (с исключениями, такими как android.arch. *). То же самое относится к докладчикам.
В соответствии с этим я должен разместить свои службы Android на вершине иерархии компонентов архитектуры на том же уровне, что и мои действия и фрагменты. Это потому, что Android Services являются частью платформы Android, поэтому ViewModels не должны знать о них.
Теперь я кратко расскажу о своем сценарии, но только для того, чтобы сделать панораму более ясной, а не потому, что я хочу получить ответ на этот конкретный сценарий.
- У меня есть приложение для Android, в котором есть MainActivity со многими фрагментами в нем, все из которых связаны друг с другом в BottomNavBar.
- У меня есть BluetoothService, связанный с myActivity и одним из его фрагментов (потому что я хочу, чтобы служба имела тот же жизненный цикл, что и Activit, но я также хочу взаимодействовать с ней непосредственно из моего фрагмента).
- Фрагмент взаимодействует с BluetoothService для получения двух типов информации:
- Информация о состоянии соединения Bluetooth. Не нужно настаивать.
- Данные, поступающие с устройства Bluetooth (это масштаб, поэтому вес и состав тела в этом случае). Нужно продолжать.
Вот три разных архитектуры, о которых я могу думать:
LiveData внутри AndroidService
- LiveData с состоянием соединения и измерениями веса, поступающими с устройства Bluetooth, находятся внутри BluetoothService.
- Фрагмент может запускать операции в BluetoothService (например, scanDevices)
- Фрагмент наблюдает за LiveData о состоянии соединения и соответствующим образом адаптирует пользовательский интерфейс (например, включите кнопку, если состояние подключено).
- Фрагмент наблюдает за LiveData новых измерений веса. Если новое измерение веса происходит из BluetoothDevice, то Fragment сообщает своей собственной ViewModel, чтобы сохранить новые данные. Это делается через класс репозитория.
Shared ViewModel между фрагментом и AndroidService
- Фрагмент может запускать операции в BluetoothService (например, scanDevices)
- BluetoothService обновляет связанные с Bluetooth LiveData в общей модели ViewModel.
- Фрагмент наблюдает за LiveData в собственной ViewModel.
- Фрагмент может запускать операции в BluetoothService (например, scanDevices)
- BluetoothService обновляет связанные с Bluetooth LiveData в собственной ViewModel.
- Фрагмент наблюдает за LiveData в собственной ViewModel и в ViewModel BluetoothService.
Я уверен, что я должен разместить их поверх архитектуры и рассматривать их так же, как Activity/Fragment, потому что BoundServices являются частью Android Framework, они управляются ОС Android, и они связаны с другими действиями и фрагментами. В этом случае я не знаю, как лучше всего взаимодействовать с LiveData, ViewModels и Activities/Fragments.
Некоторые могут подумать, что их следует рассматривать как DataSource (поскольку в моем случае он получает данные из шкалы с использованием Bluetooth), но я не думаю, что это хорошая идея, из-за всего, что я сказал в предыдущем абзаце и особенно из-за того, что он говорит здесь:
Избегайте назначения точек входа в приложение, таких как действия, службы и широковещательные приемники, в качестве источников данных. Вместо этого они должны только координировать работу с другими компонентами для извлечения подмножества данных, относящихся к этой точке входа. Каждый компонент приложения довольно короткоживущий, в зависимости от взаимодействия пользователя с их устройством и общего текущего состояния системы.
Итак, наконец, мой вопрос:
Где мы должны размещать наши Android-приложения (Bound) и каково их отношение к другим архитектурным компонентам? Является ли какой-либо из этих альтернатив хорошим подходом?