Acceder a las dependencias de actividad inyectadas por Hilt desde componentes componibles mediante CompositionLocal de Milosz Lewandowski | Febrero de 2022


Al diseñar la arquitectura de su aplicación de Android, debe decidir cómo estructurar las diferentes capas de la aplicación (y los objetos dentro de ellas), cómo se comportan o cómo funcionan juntas para formar un enfoque coherente para la introducción de nuevas funciones.
Además, a menudo se trata de dependencias de código. Muchos de estos son parte de la capa de lógica comercial o de datos y, a menudo, están separados del sistema operativo (por ejemplo, repositorios). Sin embargo, otros necesitan acceso a componentes específicos de Android, como Actividad.Es una buena idea basar su aplicación en un marco de inyección de dependencia moderno, p. resolver Administre las dependencias y amplíelas de acuerdo con su ciclo de vida.
Supongamos que queremos usar etiqueta personalizada Se utiliza para navegar a los usuarios a un sitio web.Se requiere algún código de utilidad para iniciar correctamente las pestañas personalizadas (ver Ejemplo de aplicación) y el contexto de actividad que inicia la intención; definamos una interfaz y envolvamos el código en una clase de implementación para que pueda reutilizarse en toda la aplicación:
Como puede ver, hemos utilizado la inyección de constructores y @ActivityContext
clasificatorios Haga la API un poco más simple.cada vez que queremos llamar launch
y no hay forma de abusar de la API al proporcionar un contexto de aplicación o servicio.A continuación, necesitamos crear un módulo Hilt, declararlo incluido en ActivityComponent
y vincule la implementación a la interfaz en un ámbito específico:
Ahora, podemos inyectar nuestra utilidad en la Actividad:
Estamos listos para llamar a la utilidad desde la Actividad. Pero, ¿y si seguimos el patrón de Actividad única y toda nuestra aplicación se basa en Jetpack Compose?Una forma es a través CustomTabs
Pase explícitamente la composición al objeto.Sin embargo, no todos los Composables requieren CustomTabs
objetos, que pueden estar en diferentes módulos de Gradle. La mayoría de ellos simplemente pasarán la utilidad a otro Composable. Esta solución puede volverse rápidamente ilegible y difícil de mantener.
locales combinados es una forma de pasar objetos implícitamente a través de la composición. Hay dos formas de crear CompositionLocal con diferentes significados:
- si utiliza
compositionLocalOf
El valor proporcionado por la API y CompositionLocal cambia durante el proceso de reorganización, solo leyendocurrent
El valor de CompositionLocal será invalidado, - si utiliza
staticCompositionLocalOf
Los valores proporcionados por la API y CompositionLocal se modifican durante el proceso de reorganización y todo el contenido no será válido.
En nuestro caso queremos ofrecer CustomTabs
A través de la utilidad CompositionLocal.nunca cambia Activity
de por vida, así que para obtener algunos beneficios de rendimiento usaremos staticCompositionLocalOf
.
Sigamos adelante y ejecutemos.Prefijar su ComposiciónLocal es un buen patrón Local
Además, al crear el CompositionLocal, debemos proporcionar un valor predeterminado.Nuestra interfaz de utilidad no tiene valores predeterminados, por lo tanto, deje que todas las llamadas a los valores de CompositionLocal fallen antes de vincular CustomTabs
Impleméntalo.
En nuestra actividad necesitamos llamar CompositionLocalProvider
enlazar inyectado CustomTabs
Implementación de Composición Local:
¡Eso es!Ahora, en cualquier Composable bajo el árbol de composición, puedes llamar LocalCustomTabs.current
y utilícelo para iniciar una pestaña personalizada:
Todas las soluciones son geniales hasta que las usamos en exceso.Por ejemplo, suponga que en la arquitectura de su aplicación utiliza Ver modelo con empuñadura, y su dependencia se puede hacer en toda la aplicación al incluir el módulo que la proporciona SingletonComponent
En este caso, cuando necesite llamar a las dependencias, es mejor delegar la ejecución del Composable al ViewModel.