Search code examples
androidandroid-lifecycleandroid-architecture-components

When to unregister LifecycleObserver


I'm working on a project using architecture components and I have a question about correct use of LifecycleObserver pattern.

The thing is: when should I unregister the observer and what happen if there is no unregister called?

The simple straightforward use case can looks like this:

public class MyActivity extends LifecycleActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        getLifecycle().addObserver(someLifecycleObserver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ...
        getLifecycle().removeObserver(someLifecycleObserver);
    }
}

This is probably no brainer and correct use. But with more observers there will be a lot of this boilerplate code.

Ok, now let's add Dagger into this. We can make Dagger to inject this 'someLifecycleObserver' object into the Activity (and other places like fragments).

The simple Dagger module can looks like this:

@Module
public class ConfigurationManagerModule {

    @Provides
    @ActivityScope
    SomeManager provideSomeManager(final AppCompatActivity activity, final Object otherDependency) {
        return new SomeManager(activity, otherDependency);
    }
}

Then in Activity we need to register / unregister the observer. But what if we could get rid of the registration and let the Dagger do it.

    @Provides
    @ActivityScope
    SomeManager provideSomeManager(final AppCompatActivity activity, final Object otherDependency) {
        final SomeManager manager = new SomeManager(activity, otherDependency);
        activity.getLifecycle().addObserver(manager);
        return manager;
    }

Cool everything works without adding register call inside the Activity. But wait! There is no unregister. Who's going to unregister the observer? Do we have a leak here?

So after all we have to add the unregister call inside the onDestroy of Activity to unregister the injected object. But if the object is injected in the Fragments as well we don't want to unregister it there. Only in Activity - this makes is difficult to maintain because you have to remember (if you know it in the first place) to somehow clean after the Dagger injection.

There is another solution which is kind of grey zone from my point of view. The object is registered to the Lifecycle so it will technically get onDestroy event and it can get LifecycleOwner as a parameter. So practically we can do this:

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy(LifecycleOwner source) {
    source.getLifecycle().removeObserver(this);
}

It works but I don't think it is the way to go. What are you thoughts and/or patterns for this. Can you recommend the way how you beat this problem without using a lot of boilerplate code in your Activities?

Thank you.


Solution

  • Short answer: No, LifecycleObserver automatically un-register themselves.

    Description: The purpose of LifecycleObserver is to eliminate writing the boilerplate code to load and cleanup resources in onCreate() and onDestory() respectively and if we need to do the same like unregistering it in onDestory() destroys the purpose of LifecycleObserver.

    You'll need to unregister manually in case you use observeForever kind of thing.

    More about it: https://github.com/googlecodelabs/android-lifecycles/issues/5

    EDIT: I'm not sure about Dagger. While the last approach seems bad code to me, as it destroys readability.