0
votes

Observez Livedata avec un délai initial

J'ai une liiveta qui émet chaque fois qu'il existe une mise à jour dans la base de données. Lorsque l'écran en question s'ouvre, cette liiveta émet immédiatement avec toute la valeur dans la base de données. Ensuite, un appel réseau est effectué pour mettre à jour la base de données. Une fois la base de données mise à jour, les liivata émet à nouveau. Cela conduit à deux émissions de succession très rapide. Les mises à jour ultérieures de la base de données fonctionnent correctement CZ Il n'y a qu'une seule émission chaque fois que la base de données est mise à jour. Seulement la première fois, il y a 2 mises à jour en succession très rapide. Je veux éviter ça.

Une idée à éviter ce serait quelque chose comme ça. Lorsque les liivres émettent, attendez XS. S'il y a une autre émission dans ces XS, jetez les données de l'ancienne émission et utilisez le nouveau. Attendez à nouveau xs. S'il n'y a pas d'émission dans ces XS, utilisez les dernières données.

Ceci semble très similaire pour étrangler mais une seule fois. Je me demandais s'il y a un moyen simple de faire quelque chose comme en utilisant Liveata ou Mediatorlivedata.


2 commentaires

Hey, je suis un peu confus, vous avez une Liveta qui observe une donnée, lorsque les données ont changé, vous souhaitez appeler la demande de réseau et après que notre LiveData rappellera à nouveau. Nous avons deux émissions, une activité à la première fois commence et Une fois après la demande de réseau, vous souhaitez désactiver la première observation d'une première observation?


Oui. genre de comme ça. Je ne veux pas désactiver la première émission cependant. Je veux l'utiliser s'il n'y a pas d'autre émission XS après la première émission. S'il y a une émission au sein de ces XS, je veux répéter le processus.


3 Réponses :


0
votes

Vous pouvez poster le retardé Runnable avec le délai d'attente que vous souhaitez après le premier LivetaA événement. Chaque LivetaA Mise à jour Supprimer le publié Runnable et le postez à nouveau.


0 commentaires

0
votes

Vous pouvez utiliser MediatorLivedata et un Val booléen pour y parvenir.

  1. Créez un MDBlivedata, Mediator Liveta AMFinallivedata et Boolean Mloadedfromapi Lorsque des données d'API sont chargées. LI>
  2. sur le succès ou l'échec de l'API, définissez Mloaderdfromapi sur True; Li>
  3. Observez MFinallivedata dans votre activité / fragment Li> OL>
    LiveData<Model> mDbLiveData;
    MediatorLiveData<Model> mFinalLiveData = new MediatorLiveData();
    private boolean mLoadedFromAPI = false;
    
    // Load db data in mDbLiveData
    mDbLiveData = // Data from DB
    // Add mDbLiveData as source in mFinaliveData
    mFinalLiveData.addSource(mDbLiveData, dbData -> {
        if (mLoadedFromAPI) mFinalLiveData.postValue(dbData);
    });
    
    


1 commentaires

La Livedata est renvoyée par un autre SDK. Je n'ai pas d'informations sur quand l'API a-t-il appelé.



0
votes

Ce post a aidé. https://medium.com/@ Guilherme.Devel / Throttle-opérateur-avec-LiveData-and-Kotlin-Coroutines-EC42F8CBC0B0

J'ai modifié la solution un peu pour adapter mon USECASE: P>

fun <T> LiveData<T>.debounceOnce(duration: Long,
                                 coroutineContextProvider: CoroutineContextProvider): LiveData<T> {
    return MediatorLiveData<T>().also { mediatorLivedata ->
        var shouldDebounce = true
        var job: Job? = null
        val source = this

        mediatorLivedata.addSource(source) {
            if (shouldDebounce) {
                job?.cancel()
                job = CoroutineScope(coroutineContextProvider.IO).launch {
                    delay(duration)
                    withContext(coroutineContextProvider.Main) {
                        mediatorLivedata.value = source.value
                        shouldDebounce = false
                    }
                }
            } else {
                job?.cancel()
                mediatorLivedata.value = source.value
            }
        }
    }
}

open class CoroutineContextProvider @Inject constructor() {
    open val Main: CoroutineContext by lazy { Dispatchers.Main }
    open val IO: CoroutineContext by lazy { Dispatchers.Default }
}


0 commentaires