diff --git a/src/main/java/com/infomaniak/lib/core/utils/SingleLiveEvent.kt b/src/main/java/com/infomaniak/lib/core/utils/SingleLiveEvent.kt index fecf534d..b14d1f09 100644 --- a/src/main/java/com/infomaniak/lib/core/utils/SingleLiveEvent.kt +++ b/src/main/java/com/infomaniak/lib/core/utils/SingleLiveEvent.kt @@ -36,16 +36,20 @@ import java.util.concurrent.atomic.AtomicBoolean * * Note that only one observer is going to be notified of changes. */ -class SingleLiveEvent : MutableLiveData { +@Deprecated( + "SingleLiveEvent won't stop triggering if observed using observeForever(). UniqueLiveEvent solves this issue by making notifications truly unique among observe() and observeForever().", + replaceWith = ReplaceWith("UniqueLiveEvent"), +) +open class SingleLiveEvent : MutableLiveData { - private val pending = AtomicBoolean(false) + protected val pending = AtomicBoolean(false) constructor() : super() constructor(value: T) : super(value) @MainThread override fun observe(owner: LifecycleOwner, observer: Observer) { - if (hasActiveObservers()) Log.w(TAG, "Multiple observers registered but only one will be notified of changes.") + if (hasActiveObservers()) Log.w(TAG, MULTIPLE_OBSERVER_WARNING) // Observe the internal MutableLiveData super.observe(owner) { t -> if (pending.compareAndSet(true, false)) observer.onChanged(t) } @@ -65,7 +69,8 @@ class SingleLiveEvent : MutableLiveData { value = null } - private companion object { + protected companion object { const val TAG = "SingleLiveEvent" + const val MULTIPLE_OBSERVER_WARNING = "Multiple observers registered but only one will be notified of changes." } } diff --git a/src/main/java/com/infomaniak/lib/core/utils/UniqueLiveEvent.kt b/src/main/java/com/infomaniak/lib/core/utils/UniqueLiveEvent.kt new file mode 100644 index 00000000..4f8dfb4a --- /dev/null +++ b/src/main/java/com/infomaniak/lib/core/utils/UniqueLiveEvent.kt @@ -0,0 +1,39 @@ +/* + * Infomaniak Core - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.lib.core.utils + +import android.util.Log +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.Observer + +/** + * "Now with 100% more uniqueness to it!". + * + * [UniqueLiveEvent] single notification is now shared between [observe] and [observeForever]. + * + * This has for a side effect that [UniqueLiveEvent] will only trigger once even if used with [MediatorLiveData] which is not + * backward compatible with [SingleLiveEvent]. + */ +class UniqueLiveEvent : SingleLiveEvent() { + override fun observeForever(observer: Observer) { + if (hasActiveObservers()) Log.w(TAG, MULTIPLE_OBSERVER_WARNING) + + // Observe the internal MutableLiveData + super.observeForever { t -> if (pending.compareAndSet(true, false)) observer.onChanged(t) } + } +}