TheHebrewHammer
TheHebrewHammer

Reputation: 3148

Android lifecycle library: Cannot add the same observer with different lifecycles

I have an app I'm working on that's using the lifecycle library but I'm getting an IllegalArgumentException that says "Cannot add the same observer with different lifecycles" I only add observers in onCreate which I thought would be safe. Most of my observers are added via anonymous classes which I assume can't be the issue here since the observer is never recycled. One is using this:

private GpsState gpsState;

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

In this example GpsState extends LiveData to provide the current state of the GPS and implements LifecycleObserver to be able to refresh certain values when reaching an ON_RESUME state.

Any idea what I might be doing wrong?

Upvotes: 48

Views: 26878

Answers (4)

Gilad Raz
Gilad Raz

Reputation: 155

I had the same issue, these lines of code solved it:

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

Upvotes: 7

Osvel Alvarez Jacomino
Osvel Alvarez Jacomino

Reputation: 739

Based on previous responses all you need to do is create a new Object every time you subscribe your observer.

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

PD: I assumed that GpsState is the data type you want observe. In my case was Long

Upvotes: 4

Kevin Robatel
Kevin Robatel

Reputation: 8386

As thehebrewhammer said in a comment, I had the same issue because of Kotlin SAM-Lambda optimization.

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

This SAM-Lambda doesn't access anything of the class and will be compiled to a singleton for optimization.
I changed it to a class initialization for forcing new instance at each run:

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

and

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

Upvotes: 43

Nokuap
Nokuap

Reputation: 2379

In my case the problem was at lambda method of observer is empty. I just tried to add something to it and problem was solved. For example:

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

});

Most likely that JVM define anonymous classes that use only static references and for such cases it become kinda singleton, so you will have same instance all the time you reference such class.

Upvotes: 90

Related Questions