Contexto en Jetpack Compose: Guía completa con ejemplos de código

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué el Context en Jetpack Compose es un dolor de cabeza para los principiantes?

\n

Si alguna vez ha escrito en Android usando XML, sabe que Context es literalmente la «clave» de todo: desde el acceso a recursos hasta iniciar nuevas Activities. Pero cuando pasa a Jetpack Compose, todo cambia. Las funciones componibles no tienen acceso directo al Context, y esto a menudo se convierte en un obstáculo para los desarrolladores, especialmente aquellos que recién comienzan a dominar el enfoque declarativo.

\n

La pregunta «How to get Context in Jetpack Compose» en Stack Overflow ha acumulado miles de visitas y docenas de respuestas. Esto no es casualidad. En este artículo, analizaremos todas las formas posibles de obtener Context en Compose, desde las simples hasta las avanzadas, con ejemplos de código reales en Kotlin. Aprenderá cuándo usar LocalContext.current, cómo evitar fugas de memoria y qué prácticas se consideran «best practices» en 2025.

\n\n

1. La forma más simple: LocalContext.current

\n

Si necesita obtener el Context dentro de una función componible, la forma más directa es usar LocalContext.current. Este es un composable-local que proporciona el Context actual (generalmente una Activity o un ContextWrapper).

\n\n
@Composable\nfun MyScreen() {\n    val context = LocalContext.current\n    \n    Button(onClick = {\n        Toast.makeText(context, "¡Hola desde Compose!", Toast.LENGTH_SHORT).show()\n    }) {\n        Text("Mostrar Toast")\n    }\n}
\n\n

Este código funciona, pero hay un detalle: LocalContext.current le proporciona un Context que está vinculado al CompositionLocal actual. En la mayoría de los casos, esto es lo que necesita. Sin embargo, recuerde que este Context no debe pasarse a una ViewModel ni almacenarse en objetos de larga duración, ya que podría provocar fugas de memoria.

\n\n

¿Cuándo usarlo?

\n
    \n
  • Para acciones únicas en la UI: Toast, Snackbar, iniciar una Activity.
  • \n
  • Para acceder a recursos: context.getString(R.string.app_name).
  • \n
  • Para trabajar con servicios del sistema: context.getSystemService().
  • \n
\n\n

2. Context en ViewModel: El enfoque correcto

\n

Uno de los errores más comunes es pasar el Context directamente a una ViewModel. En Android Architecture Components, esto se considera un antipatrón, ya que una ViewModel puede sobrevivir a la Activity y el Context quedará obsoleto. En su lugar, use AndroidViewModel.

\n\n
class MyViewModel(application: Application) : AndroidViewModel(application) {\n    \n    private val context = getApplication<Application>().applicationContext\n    \n    fun loadData() {\n        // Usamos applicationContext, que es seguro\n        val prefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)\n    }\n}
\n\n

En Compose, puede obtener una instancia de dicha ViewModel de la forma estándar:

\n\n
@Composable\nfun MyScreen() {\n    val viewModel: MyViewModel = viewModel()\n    // El Context ya está dentro de la ViewModel, no es necesario pasarlo desde la UI\n}
\n\n

Ventaja: applicationContext vive mientras el proceso esté vivo y no depende del ciclo de vida de la Activity. Es seguro y recomendado por Google.

\n\n

3. Context en CompositionLocal: Proveedores personalizados

\n

A veces necesita pasar un Context específico (por ejemplo, para pruebas o para un módulo con una biblioteca). En estos casos, puede crear su propio CompositionLocal.

\n\n
val LocalCustomContext = staticCompositionLocalOf<Context> {\n    error("No se proporcionó un contexto personalizado")\n}\n\n@Composable\nfun CustomContextProvider(context: Context, content: @Composable () -> Unit) {\n    CompositionLocalProvider(LocalCustomContext provides context) {\n        content()\n    }\n}\n\n// Uso:\n@Composable\nfun MyScreen() {\n    val customContext = LocalCus                

Blogs

Book Recommendations