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.collectvous 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 userDateretournés devraient en effet rester identiques après les changements de disponibilité. UserLe comportement par défaut de Kotlin Flowest 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' mapopé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

Posts les plus consultés de ce blog

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

Détecter les appuis sur les touches fléchées en JavaScript

Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"