Androidの設定情報を保存する方法として、SharedPreferencesが主流でしたが、DataStoreに移行した方が良さそうなので、導入手順を記載します。
また、DIのHiltを使用する前提で記載します。
DataStoreの導入
implementation("androidx.datastore.datastore-preferences:1.1.1")
Hilt
AppModuleとしてますが、別のModuleとしても問題ありません。
preferencesDataStoreFileで指定しているのが、ファイル名になります。
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Singleton
@Provides
fun providePreferencesDataStore(@ApplicationContext context: Context): DataStore<Preferences> {
return PreferenceDataStoreFactory.create(
produceFile = {
context.preferencesDataStoreFile("preferences")
}
)
}
}
キーを作成
キーは、保存したい値の型で作成します。
PreferencesKeys.kt
object PreferencesKeys {
val SAMPLE = intPreferencesKey("sample")
val SIMPLE = stringPreferencesKey("simple")
}
値の保存
DataStoreに値を保存する方法と使い方を記載します。
PreferencesRepository.kt
class PreferencesRepository @Inject constructor(
private val dataStore: DataStore<Preferences>
) {
suspend fun saveSample(value: Int) {
dataStore.edit { preferences ->
preferences[PreferencesKeys.SAMPLE] = value
}
}
}
MainViewModel.kt
@HiltViewModel
class MainViewModel @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : ViewModel() {
fun setSample(value: Int) {
viewModelScope.launch {
preferencesRepository.saveSample(value)
}
}
}
値の取得
同じPreferencesRepositoryとViewModelで実施しますが、分けて記載します。
emitすることで、UIに通知します。
PreferencesRepository.kt
class PreferencesRepository @Inject constructor(
private val dataStore: DataStore<Preferences>
) {
suspend fun readSample(): Int {
return dataStore.data.map { preferences ->
preferences[PreferencesKeys.SAMPLE] ?: 0
}.first()
}
}
MainViewModel.kt
@HiltViewModel
class MainViewModel @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : ViewModel() {
private val _sampleState = MutableSharedFlow<Int>()
val sampleState = _sampleState.asSharedFlow()
fun getSample() {
viewModelScope.launch {
val value = preferencesRepository.readSample()
_sampleState.emit(value)
}
}
}
まとめ
DataStoreは、非同期で動作するので少し癖がありますが、DataStoreへの移行を勧められてますので、是非移行していきましょう。