Skip to content

Most visited

Recently visited

navigation

Handling Lifecycles

The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components — which are components that can automatically adjust their behavior based on the current lifecycle of an activity or fragment.

Most of the app components that are defined in the Android Framework have lifecycles attached to them. These lifecycles are managed by the operating system or the framework code running in your process. They are core to how Android works and your application must respect them. Not doing so may trigger memory leaks or even application crashes.

Imagine we have an activity that shows the device location on the screen. A common implementation might be like the following:

class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
  }

    public void onStart() {
        super.onStart();
        myLocationListener.start();
    }

    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

Even though this sample looks fine, in a real app, you end up having way too many calls like this and the onStart() and onStop() methods become very large.

Moreover, some components cannot be just started in onStart(). What if we needed to check some configuration before starting the location observer? It is possible that in some cases the check finishes after the activity is stopped, which means that myLocationListener.start() is called after myLocationListener.stop() is called, basically keeping the connection forever.

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {
            // update UI
        });
    }

    public void onStart() {
        super.onStart();
        Util.checkUserStatus(result -> {
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }

    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

The android.arch.lifecycle package provides classes and interfaces that help you tackle these problems in a resilient and isolated way.

Lifecycle

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

Lifecycle uses two main enumerations to track the lifecycle status for its associated component.

Event
The lifecycle events that are dispatched from the framework and the Lifecycle class. These events map to the callback events in activities and fragments.
State
The current state of the component tracked by the Lifecycle object.

Think of the states as nodes of a graph and events as the edges between these nodes.

A class can monitor the component's lifecycle status by adding annotations to its methods.

public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
    }
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

LifecycleOwner

LifecycleOwner is a single method interface that denotes that the class has a Lifecycle. It has one method, getLifecycle(), which must be implemented by the class.

This class abstracts the ownership of a Lifecycle from individual classes (for example, activities and fragments) and allows writing components that can work with both of them. Any custom application class can implement the LifecycleOwner interface.

For the example above, we can make our MyLocationListener class a LifecycleObserver and then initialize it with our Lifecycle in onCreate. This allows the MyLocationListener class to be self-sufficient, meaning that it can do its own cleanup when necessary.

class MyActivity extends LifecycleActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

A common use case is to avoid invoking certain callbacks if the Lifecycle is not in a good state right now. For example, if the callback runs a fragment transaction after the activity state is saved, it would trigger a crash, so we would never want to invoke that callback.

To make this use case easy, the Lifecycle class allows other objects to query the current state.

class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        if (lifecycle.getState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        // disconnect if connected
    }
}

With this implementation, our LocationListener class is completely lifecycle-aware; it can do its own initialization and cleanup without being managed by the activity. If we need to use our LocationListener from another activity or another fragment, we just need to initialize it. All of the setup and teardown operations are managed by the class itself.

Classes that can work with a Lifecycle are called lifecycle-aware components. Libraries that provide classes that need to work with the Android lifecycle are encouraged to provide lifecycle-aware components, so that their clients can easily integrate those classes without manual lifecycle management on the client side.

LiveData is an example of a lifecycle-aware component. Using LiveData together with ViewModel makes it much easier to populate UIs with data while respecting Android lifecycles.

Best practices for Lifecycles

Addendum

Event.ON_STOP and onSaveInstanceState

When a Lifecycle belongs to an Activity or Fragment, the Lifecycle's state is moved to CREATED and ON_STOP is dispatched when the Activity or Fragment's onSaveInstanceState is called.

When a Fragment or Activity's state is saved (via onSaveInstanceState), its UI is considered immutable until onStart is called. Trying to modify UI after state is saved is likely to cause inconsistencies in the navigation state of your application which is why FragmentManager throws an exception if the app runs a FragmentTransaction after state is saved. (See FragmentTransaction#commit for details.)

LiveData prevents this edge case out of the box by refraining from calling its observer if the observer's associated Lifecycle is not at least STARTED. Behind the scenes, it calls Lifecycle#isAtLeast before deciding to invoke its observer.

Unfortunately, Activity's onStop is called after onSaveInstanceState, which leaves a gap where UI state changes are not allowed but the Lifecycle has not yet been moved to the CREATED state.

To prevent this issue, lifecycles versions beta2 and lower mark the state as CREATED without dispatching the event so that any code that checks the current state will get the real value even though the event is not dispatched until onStop is called by the system.

Unfortunately, this solution has 2 major problems:

To make this flow simpler and provide better compatibility with older versions, starting at version 1.0.0-rc1, Lifecycles will be marked CREATED and ON_STOP will be dispatched when onSaveInstanceState is called without waiting for an onStop call. This is unlikely to impact your code but it is something you need to be aware of as it does not match the call order in the Activity class for Android OS versions 26 and before.

Implementing LifecycleOwner in custom activities and fragments

Fragments and Activities in Support Library 26.1.0 and later already implement the LifecycleOwner interface.

If you have a custom class that you would like to make a LifecycleOwner, you can use the LifecycleRegistry class, but you will need to forward events into that class.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)