0Pricing
Android Academy · レッスン

DataStore Preferences

SharedPreferencesを最新のDataStoreライブラリに置き換えます。データをKotlin Flowとして読み取り、edit{}で書き込み、安全にエラーを処理する方法を学びます。

「DataStore Preferences」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン5/6です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全6レッスンが含まれています。

なぜDataStoreを使うのか

DataStoreは、SharedPreferencesに代わる最新の仕組みです。次のような実際の問題を解決します。

  • SharedPreferencesはUIスレッドをブロックしますが、DataStoreは完全に非同期です
  • SharedPreferencesはキャッチされない例外をスローする可能性がありますが、DataStoreはFlowを通じてエラーを処理します
  • DataStoreは型安全(Preferences)またはスキーマ安全(Proto)です
  • Kotlin CoroutinesとFlowをネイティブに使用できます

DataStoreの2つの種類

用途に合った種類を選択してください。

  • Preferences DataStore — キーと値のペアを扱い、スキーマは必要ありません。最も簡単にセットアップできます。アプリの設定やユーザー設定に適しています。
  • Proto DataStore — Protocol Buffersを使用して型付きオブジェクトを扱います。.protoスキーマファイルが必要です。構造化されたデータを扱う場合に適しています。

このレッスンではPreferences DataStoreを扱います。

依存関係の追加

app/build.gradleにDataStoreを追加します。

// 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での収集

効率よく収集できるようにstateInを使い、ViewModelからDataStoreのFlowを公開します。

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での監視

lifecycleScope.launchを使い、UIでStateFlowを収集します。

// 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のリスクがありません
  • SharedPreferencesのapply()は暗黙的に失敗する可能性がありますが、DataStoreはFlowを通してエラーを伝播します
  • DataStoreはリアクティブで、データが変わるとUIが自動的に更新されます
  • SharedPreferencesには移行手段がありませんが、DataStoreにはSharedPreferencesMigrationが組み込まれています

理解度チェック

DataStoreがアプリの他の部分にデータを公開する際に使う主な仕組みは何ですか?

まとめ:DataStore Preferences

DataStoreは、単純なデータを永続化するための最新の方法です。

  • datastore-preferences依存関係を追加する
  • preferencesDataStoreデリゲートを使って単一のインスタンスを作成する
  • stringPreferencesKeyやbooleanPreferencesKeyなどで型安全なキーを定義する
  • コルーチン内でdataStore.edit { }を使って書き込む
  • dataStore.data.map { }を使い、Flowとして読み取る
  • .catch { emit(emptyPreferences()) }でIOExceptionを処理する

次は、DiffUtilを使って効率的なリストアダプターを構築します。

よくある質問

「DataStore Preferences」レッスンは無料ですか?

はい。「DataStore Preferences」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全6レッスンが含まれています。

「DataStore Preferences」で何を学びますか?

SharedPreferencesを最新のDataStoreライブラリに置き換えます。データをKotlin Flowとして読み取り、edit{}で書き込み、安全にエラーを処理する方法を学びます。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Android Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン5/6です。

「DataStore Preferences」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAndroid Academyレッスンでコードを書いて実行できますか?

はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Kotlinコレクション
  2. RecyclerViewの基礎
  3. RecyclerViewのクリックイベント
  4. SharedPreferences
  5. DataStore Preferences
  6. AdaptersとDiffUtil
← Android Academyに戻る