Настройки DataStore
Замените SharedPreferences современной библиотекой DataStore. Читайте данные как Kotlin Flow, записывайте их с помощью edit{} и безопасно обрабатывайте ошибки.
«Настройки DataStore» — бесплатный урок Android Academy на CoddyKit. Это урок 5 из 6. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 6 уроков всего.
Зачем нужен DataStore?
DataStore — современная замена SharedPreferences. Она решает реальные проблемы:
- SharedPreferences блокирует поток пользовательского интерфейса, а DataStore полностью асинхронен
- SharedPreferences может выдавать необработанные исключения, а DataStore обрабатывает ошибки через Flow
- DataStore обеспечивает безопасность типов (Preferences) или безопасность схемы (Proto)
- Нативно работает с Kotlin Coroutines и Flow
Два типа DataStore
Выберите подходящий тип для своего случая:
- Preferences DataStore — пары «ключ–значение», схема не требуется. Проще всего настроить. Лучше всего подходит для настроек приложения и пользовательских предпочтений.
- Proto DataStore — типизированные объекты с использованием Protocol Buffers. Требуется файл схемы .proto. Лучше всего подходит для структурированных данных.
В этом уроке рассматривается Preferences DataStore.
Добавление зависимости
Добавьте DataStore в app/build.gradle:
// app/build.gradle
dependencies {
implementation 'androidx.datastore:datastore-preferences:1.1.1'
// Coroutines (likely already in your project)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}Создание экземпляра DataStore
Создайте DataStore один раз с помощью делегата верхнего уровня. Обычно это делают в отдельном файле:
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
// Top-level property — creates a single DataStore instance per Context
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")Определение ключей
Ключи — это типобезопасные объекты, а не обычные строки. Создавайте их с помощью подходящей фабричной функции:
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
object PreferencesKeys {
val DARK_MODE = booleanPreferencesKey("dark_mode")
val USER_NAME = stringPreferencesKey("user_name")
val LAUNCH_COUNT = intPreferencesKey("launch_count")
}Запись данных
Выполняйте запись внутри корутины с помощью edit { }:
import androidx.datastore.preferences.core.edit
// In a ViewModel or Repository:
suspend fun saveDarkMode(enabled: Boolean) {
context.dataStore.edit { prefs ->
prefs[PreferencesKeys.DARK_MODE] = enabled
}
}
suspend fun incrementLaunchCount() {
context.dataStore.edit { prefs ->
val current = prefs[PreferencesKeys.LAUNCH_COUNT] ?: 0
prefs[PreferencesKeys.LAUNCH_COUNT] = current + 1
}
}Чтение данных с помощью Flow
DataStore предоставляет данные в виде Flow. Используйте map, чтобы извлечь нужное значение:
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
val darkModeFlow: Flow<Boolean> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false // default = false
}
val userNameFlow: Flow<String> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.USER_NAME] ?: "Guest"
}Сбор данных в ViewModel
Предоставляйте Flow из DataStore через ViewModel, используя stateIn для эффективного сбора данных:
class SettingsViewModel(private val repo: SettingsRepository) : ViewModel() {
val isDarkMode: StateFlow<Boolean> = repo.darkModeFlow
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = false
)
fun toggleDarkMode(enabled: Boolean) {
viewModelScope.launch {
repo.saveDarkMode(enabled)
}
}
}Наблюдение в Activity/Fragment
Собирайте StateFlow в пользовательском интерфейсе с помощью lifecycleScope.launch:
// In Fragment:
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.isDarkMode.collect { darkMode ->
binding.switchDarkMode.isChecked = darkMode
AppCompatDelegate.setDefaultNightMode(
if (darkMode) AppCompatDelegate.MODE_NIGHT_YES
else AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
)
}
}
}Обработка ошибок
DataStore выдаёт IOException, если файл повреждён. Обрабатывайте исключение в конвейере Flow:
import kotlinx.coroutines.flow.catch
import java.io.IOException
val safeFlow: Flow<Boolean> = context.dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences()) // return defaults
} else {
throw exception
}
}
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false
}DataStore и SharedPreferences
Почему DataStore лучше:
- DataStore автоматически читает и записывает данные в фоновом потоке — риск ANR отсутствует
apply()у SharedPreferences может завершиться без уведомления об ошибке, а DataStore передаёт ошибки через Flow- DataStore поддерживает реактивную работу — интерфейс автоматически обновляется при изменении данных
- У SharedPreferences нет пути миграции, а в DataStore есть встроенная
SharedPreferencesMigration
Быстрая проверка
Какой основной механизм использует DataStore, чтобы предоставлять свои данные остальной части приложения?
Итоги: Preferences DataStore
DataStore — современный способ сохранять простые данные:
- Добавьте зависимость
datastore-preferences - Создайте единственный экземпляр с помощью делегата
preferencesDataStore - Определите типобезопасные ключи с помощью
stringPreferencesKey,booleanPreferencesKeyи других функций - Записывайте данные с помощью
dataStore.edit { }внутри корутины - Читайте данные как
Flowс помощьюdataStore.data.map { } - Обрабатывайте
IOExceptionс помощью.catch { emit(emptyPreferences()) }
Далее: создание эффективных адаптеров списков с помощью DiffUtil.
Часто задаваемые вопросы
Урок «Настройки DataStore» бесплатный?
Да — полный текст урока «Настройки DataStore» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 6 уроков всего.
Чему я научусь в уроке «Настройки DataStore»?
Замените SharedPreferences современной библиотекой DataStore. Читайте данные как Kotlin Flow, записывайте их с помощью edit{} и безопасно обрабатывайте ошибки. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Android Academy?
Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 5 из 6.
Сколько времени занимает урок «Настройки DataStore»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Android Academy?
Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Коллекции Kotlin
- Основы RecyclerView
- События нажатия в RecyclerView
- SharedPreferences
- Настройки DataStore
- Адаптеры и DiffUtil