web-dev-qa-db-fra.com

Android bibliothèque de cycle de vie: impossible d'ajouter le même observateur avec différents cycles de vie

J'ai une application sur laquelle je travaille qui utilise la bibliothèque de cycle de vie mais j'obtiens une exception IllegalArgumentException qui dit "Impossible d'ajouter le même observateur avec différents cycles de vie" J'ajoute uniquement des observateurs dans onCreate que je pensais être sûrs. La plupart de mes observateurs sont ajoutés via des classes anonymes qui, je suppose, ne peuvent pas être le problème ici car l'observateur n'est jamais recyclé. L'un utilise this:

private GpsState gpsState;

void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getLifecycle().addObserver(gpsState);
    gpsState.observe(this, (state) -> {
        // ...
    });
}

Dans cet exemple, GpsState étend LiveData pour fournir l'état actuel du GPS et implémente LifecycleObserver pour pouvoir actualiser certaines valeurs lorsqu'il atteint un état ON_RESUME.

Une idée de ce que je pourrais faire de mal?

15
TheHebrewHammer

Dans mon cas, le problème était à lambda, la méthode d'observation est vide. J'ai juste essayé d'y ajouter quelque chose et le problème a été résolu. Par exemple:

gpsState.observe(this, (state) -> {
                Log.d(this.getClass().getSimpleName(), BaseNavigationActivity.this.toString());

});

Très probablement, la JVM définit des classes anonymes qui n'utilisent que des références statiques et dans de tels cas, elle devient un peu singleton, vous aurez donc la même instance tout le temps que vous référencerez une telle classe.

29
Nokuap

Comme thehebrewhammer l'a dit dans un commentaire, j'ai eu le même problème en raison de l'optimisation Kotlin SAM-Lambda.

viewModel.myLiveData.observe(this, Observer {
    NavigationBackEvent().post()
})

Ce SAM-Lambda n'accède à rien de la classe et sera compilé en un singleton pour l'optimisation.
Je l'ai changé en une initialisation de classe pour forcer une nouvelle instance à chaque exécution:

viewModel.myLiveData.observe(this, MyObserver())

et

class MyObserver : Observer<MyType?> {
    override fun onChanged(it: MyType?) {
        NavigationBackEvent().post()
    }
}
9
Kevin Robatel

J'ai eu le même problème, ces lignes de code l'ont résolu:

sharedViewModel.getFriendsList().observe(this, object: Observer<ArrayList<User>> {
    override fun onChanged(t: ArrayList<User>?) {
        CurrentUser.friendsList = t
    }
})
1
Gilad Raz

Sur la base des réponses précédentes, tout ce que vous devez faire est de créer un nouveau Object chaque fois que vous abonnez votre observateur.

gpsState.observe(this, object: Observer<GpsState> {
    // ...
});

PD: J'ai supposé que GpsState est le type de données que vous souhaitez observer. Dans mon cas était Long

0