Valeur d'émission de débit même lorsqu'il n'y a pas de changement
J'ai un magasin de données dans mon application Android où je stocke les détails de mon profil. et récupérer comme suit
suspend fun saveUser(user: User) {
dataStore.edit {
it[USER_ID] = user.id
it[USER_NAME] = user.name
it[USER_MOBILE] = user.phone
it[USER_EMAIL] = user.email
it[USER_IMAGE] = user.image
it[USER_ADDRESS] = user.address
}
}
val userDate = dataStore.data
.catch { e ->
if (e is IOException) {
Log.e("PREFERENCE", "Error reading preferences", e)
emit(emptyPreferences())
} else {
throw e
}
}
.map { pref ->
val userId = pref[USER_ID]?: ""
val userName = pref[USER_NAME]?: ""
val userEmail = pref[USER_EMAIL]?: ""
val userImage = pref[USER_IMAGE]?: ""
val userPhone = pref[USER_MOBILE]?: ""
val userAddress = pref[USER_ADDRESS]?: ""
User(
name = userName,
image = userImage,
address = userAddress,
phone = userPhone,
id = userId,
email = userEmail
)
}
Parallèlement, je sauvegarde le statut de disponibilité de l'utilisateur
suspend fun saveIsAvailable(boolean: Boolean) {
dataStore.edit {
it[USER_IS_AVAILABLE] = boolean
}
}
Je collecte les détails du profil utilisateur comme celui-ci dans mon modèle de vue
viewModelScope.launch(Default) {
RiderDataStore.userDate.collect {
user.postValue(it)
}
}
Chaque fois que je modifie la disponibilité de l'utilisateur, mon flux de détails utilisateur est également déclenché, ce qui est inutile et provoque une gigue de l'interface utilisateur (rechargement de l'image). Pourquoi cela se produit-il et comment activer le flux pour qu'il ne se déclenche que si les données changent spécifiquement des détails de l'utilisateur.
Solution du problème
En effet, vous mettez à jour une propriété utilisateur (dans DataStore
) et en même temps userDate.collect
vous observez toutes les modifications apportées à l'utilisateur (dans DataStore
). Votre code actuel n'a aucun moyen de faire la distinction entre les "bonnes" et les "mauvaises" mises à jour de l'utilisateur.
Puisque vous semblez ignorer la disponibilité dans votre DataStore
Flow
, vos objets userDate
retournés devraient en effet rester identiques après les changements de disponibilité. User
Le comportement par défaut de Kotlin Flow
est d'émettre à chaque modification, même si les données sont identiques. Mais vous pouvez résoudre ce problème simplement en ajoutant un .distinctUntilChanged()
après l' map
opérateur comme :
val userDate = dataStore.data
.catch { e ->
if (e is IOException) {
Log.e("PREFERENCE", "Error reading preferences", e)
emit(emptyPreferences())
} else {
throw e
}
}
.map { pref ->
val userId = pref[USER_ID]?: ""
val userName = pref[USER_NAME]?: ""
val userEmail = pref[USER_EMAIL]?: ""
val userImage = pref[USER_IMAGE]?: ""
val userPhone = pref[USER_MOBILE]?: ""
val userAddress = pref[USER_ADDRESS]?: ""
User(
name = userName,
image = userImage,
address = userAddress,
phone = userPhone,
id = userId,
email = userEmail
)
}.distinctUntilChanged()
Voir aussi docs. Il s'assure que des données identiques ne sont pas émises encore et encore.
Commentaires
Enregistrer un commentaire