在使用DataStore时,我们可以使用Flow和LiveData来观察数据的变化。但是,在更新单个首选项时,所有首选项都会接收更新。这是因为我们使用了DataStore的全局流。
为了避免这个问题,我们可以为每个首选项创建单独的流。这样,在更新单个首选项时,只有该首选项的观察者会接收到更新。以下是示例代码:
首先,创建一个名为UserPreferences的类,该类包含为每个首选项定义单独流的方法:
class UserPreferences private constructor(context: Context) {
private val dataStore = context.createDataStore(name = "user_preferences")
val favoriteColorFlow: Flow
get() = dataStore.data.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.map { preferences ->
preferences[KEY_FAVORITE_COLOR]
}
val isNightModeFlow: Flow
get() = dataStore.data.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.map { preferences ->
preferences[KEY_IS_NIGHT_MODE]
}
suspend fun saveFavoriteColor(color: String) {
dataStore.edit { preferences ->
preferences[KEY_FAVORITE_COLOR] = color
}
}
suspend fun saveIsNightMode(isNightMode: Boolean) {
dataStore.edit { preferences ->
preferences[KEY_IS_NIGHT_MODE] = isNightMode
}
}
companion object {
@Volatile
private var instance: UserPreferences? = null
fun getInstance(context: Context): UserPreferences {
return instance ?: synchronized(this) {
instance ?: UserPreferences(context).also {
instance = it
}
}
}
private const val KEY_FAVORITE_COLOR = "favorite_color"
private const val KEY_IS_NIGHT_MODE = "is_night_mode"
}
}
然后,我们可以为每个首选项观察者创建单独的流:
class MyViewModel(application: Application) : AndroidViewModel(application) {
private val userPreferences = UserPreferences.getInstance(application)
val favoriteColorFlow = userPreferences.favoriteColorFlow.asLiveData()
val isNightModeFlow = userPreferences.isNightModeFlow.asLiveData()
fun saveFavoriteColor(color: String) = viewModelScope.launch {
userPreferences