Lors de l'écriture d'une expression lambda au lieu de la classe interne anonyme de Java, j'ai supposé que ce serait une instance distincte, et c'est un mémo qui est devenu un problème dans la gestion de chaque instance.
Afin de réaliser que l'utilisation de LiveData des composants d'architecture Android pour fournir une source de données gérée par un LiveData comme un autre LiveData, l'implémentation suivante transmet un Observer vide à LiveData.observer. J'en étais accro.
Exemple de code
kotlin
//Contre les LiveData qui s'incrémentent toutes les secondes uniquement lors de l'observation
class Counter : LiveData<Int>() {
private var timer: Timer? = null
//LiveData qui ne fournit que des nombres pairs tout en s'appuyant sur des compteurs de classe externes
var oddCounter: MutableLiveData<Int> = object : MutableLiveData<Int>() {
override fun observe(owner: LifecycleOwner, observer: Observer<Int>) {
super.observe(owner, observer)
//Parce qu'il y a un compteur dans la classe externe
//En observant cela aussi, activez-le et démarrez le compteur.
[email protected](owner, Observer<Int> { })
}
}
override fun onActive() {
val task = object : TimerTask() {
override fun run() {
var nextCount = (value ?: 0) + 1
postValue(nextCount)
if (nextCount % 2 != 0) {
oddCounter.postValue(nextCount)
}
}
}
timer = Timer()
timer?.scheduleAtFixedRate(task, 0, 1000)
}
override fun onInactive() {
timer?.cancel()
}
}
class MainKotlinActivity : AppCompatActivity() {
private val counter = Counter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Code que les activités et les processus observent dans un exemple d'implémentation observé par plusieurs propriétaires
counter.oddCounter.observe(this, Observer<Int> { value ->
value?.let { println("activity got $it") }
})
counter.oddCounter.observe(ProcessLifecycleOwner.get(), Observer<Int> { value ->
value?.let { println("process got $it") }
})
}
}
Quand je fais cela, le code [email protected] (owner, Observer <Int> {})
est appelé deux fois pour différentes instances de ʻowner, mais la deuxième fois
java.lang.IllegalArgumentException J'obtiens l'exception: impossible d'ajouter le même observateur avec des cycles de vie différents.
La cause est la suivante.
--ʻObserver
LiveData.observe
(https://developer.android.com/reference/androidx/lifecycle/LiveData.html#observe (androidx.lifecycle.LifecycleOwner,% 2520androidx.lifecycle.Observer% 3C?% 2520super" % 2520T% 3E)), un observateur ne peut pas être utilisé par différents propriétairesProbablement, ʻObserver , c'est-à-dire que l'implémentation dépend du ʻowner
qui change à chaque appel, c'est différent. A renvoyé une instance.
En premier lieu, je pensais que le code d'octet serait complètement différent entre la classe interne anonyme et l'expression lambda, donc http://www.ne.jp/asahi/hishidama/home/tech/java/lambda.html#h_invokedynamic Lire ceci Hmmmm.
Cette fois, j'ai écrit ʻObserver
La manière la plus orthodoxe: la classe interne anonyme de Java.
java
Observer<Integer> nullObserver = new Observer<Integer>() {
@Override
public void onChanged(@Nullable Integer integer) {
}
};
observe(owner, nullObserver);
Mais cela est suggéré à Android Studio car "peut être remplacé par lambda", ce qui se traduit par du code utilisant des expressions lambda comme suit:
java
Observer<Integer> nullObserver = value -> {};
observe(owner, nullObserver);
La même chose est vraie pour Kotlin.
kotlin
val nullObserver = object : Observer<Int> {
override fun onChanged(t: Int?) {
}
}
observe(owner, nullObserver);
kotlin
val nullObserver = Observer<Int> { }
observe(owner, nullObserver);
J'ai de nouveau réalisé que je devais être conscient des différences entre eux et les utiliser correctement.
Si vous laissez simplement la classe interne anonyme d'origine ou l'expression d'objet, une autre personne peut effectuer à nouveau la même modification selon la suggestion de l'EDI, donc instanciez une classe dédiée comme suit: Je l'ai fait.
kotlin
private class NullObserver<T> : Observer<T> {
override fun onChanged(t: T?) {
}
}
observe(owner, NullObserver<Int>())
En compilant maintenant l'article de qiita, je me suis demandé s'il aurait été correct de compléter quelque chose avec des commentaires de code source.
fin.
En passant, avec l'exemple de code écrit ici, si vous utilisez Transformations, vous n'aurez pas à faire une observation du ciel aussi compliquée. Cependant, le code réel peut être un peu plus compliqué.
Recommended Posts