← Назад к вопросам

Как внутри Compose функции получить контекст

1.0 Junior🔥 221 комментариев
#Android компоненты#UI и вёрстка

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Получение контекста внутри Composable-функций

В Jetpack Compose получение контекста (Context) осуществляется через специальные механизмы, которые отличаются от традиционного подхода в View-системе. Вот основные способы:

1. LocalContext.current (наиболее рекомендуемый способ)

Этот способ использует систему Local Composition — механизм передачи зависимостей через композицию. LocalContext предоставляет текущий Context как часть окружения Composable- функций.

@Composable
fun MyComposable() {
    val context = LocalContext.current
    
    Button(onClick = {
        Toast.makeText(context, "Hello Compose!", Toast.LENGTH_SHORT).show()
    }) {
        Text("Показать Toast")
    }
}

Важно: LocalContext.current предоставляет контекст текущего Composable, который может быть:

  • Activity (если вызывается внутри Activity)
  • Application (в других случаях)

2. CompositionLocalProvider для кастомного контекста

Вы можете создать собственный CompositionLocal для передачи специализированного контекста:

val LocalCustomContext = staticCompositionLocalOf<CustomContext> { 
    error("CustomContext not provided") 
}

@Composable
fun App() {
    val customContext = remember { CustomContext() }
    
    CompositionLocalProvider(LocalCustomContext provides customContext) {
        ChildComposable()
    }
}

@Composable
fun ChildComposable() {
    val customContext = LocalCustomContext.current
    // Используем customContext
}

3. Ambient (устаревший способ, используйте CompositionLocal)

В ранних версиях Compose использовался термин Ambient, который был заменен на CompositionLocal:

// УСТАРЕЛО - НЕ ИСПОЛЬЗУЙТЕ!
@Composable
fun DeprecatedWay() {
    val context = AmbientContext.current // Теперь это LocalContext
}

4. remember с ActivityResultRegistry (для специальных случаев)

Для работы с ActivityResultLauncher или другими компонентами, требующими Activity-контекста:

@Composable
fun ActivityResultExample() {
    val context = LocalContext.current
    val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) { result ->
        // Обработка результата
    }
    
    // Использование launcher
}

5. Проблемы и ограничения при получении контекста

Важные предупреждения:

  • Не сохраняйте контекст в remember без причины: Контекст может меняться (например, при смене конфигурации)
// ПЛОХО - может привести к утечке памяти
@Composable
fun WrongWay() {
    val context = remember { LocalContext.current } // ❌
}

// ХОРОШО - получаем текущий контекст при каждом вызове
@Composable
fun CorrectWay() {
    val context = LocalContext.current // ✅
}
  • Используйте правильный тип контекста: Для разных задач нужен разный контекст:
    • Activity для startActivity(), диалогов
    • Application для долгоживущих операций
    • UI Context для работы с ресурсами

6. Практический пример с несколькими способами

@Composable
fun ContextUsageExamples() {
    // Основной способ
    val context = LocalContext.current
    
    Column {
        // Пример с Toast
        Button(onClick = {
            Toast.makeText(context, "Сообщение", Toast.LENGTH_SHORT).show()
        }) {
            Text("Toast")
        }
        
        // Пример с ресурсами
        Text(
            text = context.getString(R.string.app_name),
            color = Color(context.getColor(R.color.primary))
        )
        
        // Пример с SharedPreferences
        Button(onClick = {
            val prefs = context.getSharedPreferences("app", Context.MODE_PRIVATE)
            prefs.edit().putString("key", "value").apply()
        }) {
            Text("Сохранить в Prefs")
        }
    }
}

7. Лучшие практики

  1. Используйте LocalContext.current как основной способ
  2. Избегайте долгоживущих ссылок на контекст в remember
  3. Для View-интеропов используйте AndroidView с правильным контекстом:
@Composable
fun WebViewExample(url: String) {
    AndroidView(
        factory = { context ->
            WebView(context).apply {
                loadUrl(url)
            }
        }
    )
}
  1. Для тестирования мокируйте LocalContext через CompositionLocalProvider
@Composable
fun TestableComposable(context: Context = LocalContext.current) {
    // Более тестируемая версия
}

Получение контекста в Compose стало более декларативным и безопасным благодаря системе CompositionLocal, которая обеспечивает явную передачу зависимостей и упрощает тестирование ваших Composable- функций.

Как внутри Compose функции получить контекст | PrepBro