es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Servicios enlazados en el patrón MVVM

Estoy trabajando en una aplicación de Android (en Java) y tratando de utilizar la arquitectura de aplicación recomendada por Google, pero no puedo encontrar la forma en que los servicios encajan en esta arquitectura. He buscado mucho en línea y parece que no hay un consenso claro sobre cómo debería hacerse.

Para contextualizar, mi aplicación comunica con un dispositivo BLE. He creado BLEService que extiende Service para establecer la conexión con el dispositivo y proporcionar métodos para enviar datos al dispositivo. El dispositivo también puede enviar datos de vuelta (y por lo tanto necesita notificar a la aplicación cuando se reciben datos).

Mi pregunta es, ¿dónde debería residir la ServiceConnection y cómo debería ser detenida/iniciada? Según mi investigación, hay algunas opciones que tienen sus pros y contras.

  1. El servicio se inicia/detiene en la actividad, la actividad observa los eventos del servicio y los envía al modelo de vista para su procesamiento. Este patrón mantiene todos los componentes de Android juntos, pero da más responsabilidad a la vista de lo que creo que debería tener. La vista debería ser responsable sólo de manejar la UI.

  2. El servicio se detiene/inicia en el modelo de vista (quizás mediante la extensión de AndroidViewModel). El modelo de vista observa los eventos del servicio y procesa los eventos. Este patrón es agradable porque el modelo de vista maneja la lógica de negocio, sin embargo, si el servicio implementa sus eventos a través de LiveData, Google dice que el modelo de vista no debe observar LiveData. Otra opción es que el servicio implemente eventos a través de algo como EventBus, pero hay muchas personas en contra de usar EventBus porque es fácil de abusar. También he oído que el modelo de vista no debe tener código específico de Android para fines de prueba.

  3. El servicio existe en algún tipo de repositorio/modelo. El modelo de vista envía y observa eventos del repositorio/modelo. Esta solución es útil porque el uso de un dispositivo Bluetooth parece encajar con el propósito previsto de lo que es un modelo. Sin embargo, sufre el mismo problema de que el modelo de vista no debe observar LiveData. He visto sugerido en este caso el uso de Transformations.switchMap, que hace que un LiveData en el modelo de vista se actualice en respuesta a un cambio en un LiveData del repositorio. No estoy totalmente claro en el uso de esta estrategia, o cómo funcionaría en mi caso específico. También está la cuestión de que el repositorio necesita acceso a Context, y he oído que es mala práctica mantener una instancia de Context. Además, también he leído que un repositorio no debe mantener callbacks de la modelo de vista.

Estoy seguro de que no hay una solución perfecta, pero si alguien pudiera señalarme la dirección de las mejores prácticas, particularmente en mi caso de uso, sería de gran ayuda.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en el desarrollo de Android con experiencia en Android Service, LiveData, Android Architecture Components y MVVM, puedo proporcionar una recomendación para el escenario dado.

    Al trabajar con la arquitectura recomendada de Google, es importante segregar las responsabilidades entre los componentes para garantizar una separación clara de la lógica empresarial y la interfaz de usuario. Para el escenario dado, recomendaría el segundo enfoque con ciertas modificaciones.

    El Servicio debe ser gestionado desde el ViewModel, y los eventos deben ser implementados utilizando LiveData. Sin embargo, en lugar del ViewModel observando LiveData, debería exponer instancias MutableLiveData que la Activity pueda observar. Esto mantendrá la responsabilidad del manejo de la interfaz de usuario con la Activity y permitirá que el ViewModel se centre en la lógica empresarial.

    Cuando se establece un nuevo valor en la instancia MutableLiveData, el ViewModel puede procesar los datos y actualizar cualquier otra instancia LiveData que sea necesaria. En el caso del dispositivo BLE, la instancia MutableLiveData puede almacenar los datos recibidos, y la Activity puede observarlos para actualizar la interfaz de usuario.

    Para gestionar la conexión, el ViewModel puede exponer métodos para iniciar y detener el Servicio, que pueden ser llamados desde la Activity según sea necesario. Esto garantizará que el Servicio sea gestionado desde el ViewModel, manteniendo la responsabilidad de la lógica empresarial con él.

    En cuanto a las pruebas, el ViewModel puede ser probado independientemente de la interfaz de usuario, ya que no tendrá ninguna referencia a la Activity ni a ningún código específico de Android. El Servicio también puede ser probado por separado mediante la simulación de las dependencias necesarias para comunicarse con el dispositivo BLE.

    En general, este enfoque mantendrá una separación clara de las responsabilidades, permitiendo una fácil prueba y mantenimiento de la base de código, mientras que también proporciona una solución robusta para comunicarse con el dispositivo BLE.

Comments are closed.