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

La fonction GCP Cloud pour écrire des données dans BigQuery s'exécute avec succès, mais les données n'apparaissent pas dans la table BigQuery

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

Le shell POSIX (sh) redirige stderr vers stdout et capture stderr et stdout dans des variables