Working with Android Jetpack Lifecycle-Aware Components
An earlier chapter described the use of lifecycle methods to track lifecycle state changes within a UI controller such as an activity or fragment. One of the main problems with these methods is that they place the burden of handling lifecycle changes onto the UI controller. On the surface this might seem like the logical approach since UI controller is, after all, the object going through the state change. The fact is, however, that the code that is typically impacted by the state change invariably resides in other classes within the app. This led to complex code appearing in the UI controller that needed to manage and manipulate other objects in response to changes in lifecycle state. Clearly this is a scenario best avoided when following the Android architectural guidelines.
A much cleaner and logical approach would be for the objects within an app to be able to observe the lifecycle state of other objects and to be responsible for taking any necessary actions in response to the changes. The class responsible for tracking a user’s location, for example, could observe the lifecycle state of a UI controller and suspend location updates when the controller enters a paused state. Tracking would then be restarted when the controller enters the resumed state. This is made possible by the classes and interfaces provided by the Lifecycle package bundled with the Android architecture components.
This chapter will introduce the terminology and key components that enable lifecycle awareness to be built into Android apps.
Lifecycle Awareness
An object is said to be lifecycle-aware if it is able to detect and respond to changes in the lifecycle state of other objects within an app. Some Android components, LiveData being a prime example, are already lifecycle-aware. It is also possible to configure any class to be lifecycle-aware by implementing the LifecycleObserver interface within the class.
Lifecycle Owners
Lifecycle-aware components can only observe the status of objects that are lifecycle owners. Lifecycle owners implement the LifecycleOwner interface and are assigned a companion Lifecycle object which is responsible for storing the current state of the component and providing state information to lifecycle observers. Most standard Android Framework components (such as activity and fragment classes) are lifecycle owners. Custom classes may also be configured as lifecycle owners by using the LifecycleRegistry class and implementing the LifecycleObserver interface. For example:
public class SampleOwner implements LifecycleOwner { private LifecycleRegistry lifecycleRegistry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); lifecycleRegistry = new LifecycleRegistry(this); } @NonNull @Override public Lifecycle getLifecycle() { return lifecycleRegistry; } }
Unless the lifecycle owner is a subclass of another lifecycle-aware component, the class will need to trigger lifecycle state changes itself via calls to methods of the LifecycleRegistry class. The markState() method can be used to trigger a lifecycle state change passing through the new state value:
public void resuming() { lifecycleRegistry.markState(Lifecycle.State.RESUMED); }
The above call will also result in a call to the corresponding event handler. Alternatively, the LifecycleRegistry handleLifecycleEvent() method may be called and passed the lifecycle event to be triggered (which will also result in the lifecycle state changing). For example:
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
Lifecycle Observers
In order for a lifecycle-aware component to observe the state of a lifecycle owner it must implement the LifecycleObserver interface and contain event listener handlers for any lifecycle change events it needs to observe.
public class SampleObserver implements LifecycleObserver { // Lifecycle event methods go here }
An instance of this observer class is then created and added to the list of observers maintained by the Lifecycle object.
getLifecycle().addObserver(new SampleObserver());
An observer may also be removed from the Lifecycle object at any time if it no longer needs to track the lifecycle state.
Figure 1-1 illustrates the relationship between the key elements that provide lifecycle awareness:

[[File:]]
Lifecycle States and Events
When the status of a lifecycle owner changes, the assigned Lifecycle object will be updated the new current state. At any given a time, a lifecycle owner will be in one of the following five states:
- Lifecycle.State.INITIALIZED
- Lifecycle.State.CREATED
- Lifecycle.State.STARTED
- Lifecycle.State.RESUMED
- Lifecycle.State.DESTROYED
As the component transitions through the different states, the Lifecycle object will trigger events on any observers that have been added to the list. The following events are available for implementation within the lifecycle observer:
- Lifecycle.Event.ON_CREATE
- Lifecycle.Event.ON_START
- Lifecycle.Event.ON_RESUME
- Lifecycle.Event.ON_PAUSE
- Lifecycle.Event.ON_STOP
- Lifecycle.Event.ON_DESTROY
- Lifecycle.Event.ON_ANY
Annotations are used within the observer class to associate methods with lifecycle events. The following code, for example, configures a method within a observer to be called in response to an ON_RESUME lifecycle event:
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume() { // Perform tasks in response to change to RESUMED status }
The method assigned to the ON_ANY event will be called for all lifecycle events. The method for this event type is passed a reference to the lifecycle owner and an event object which can be used to find the current state and event type. The following method, for example, extracts the names of both the current state and event:
@OnLifecycleEvent(Lifecycle.Event.ON_ANY) public void onAny(LifecycleOwner owner, Lifecycle.Event event) { String currentState = getLifecycle().getCurrentState().name(); String eventName = event.name(); }
The isAtLeast() method of the current state object may also be used when the owner state needs to be at a certain lifecycle level:
if (currentState.isAtLeast(Lifecycle.State.STARTED)) { // Perform tasks here if lifecycle owner state is at least STARTED. }
The flowchart in Figure 1-2 illustrates the sequence of state changes for a lifecycle owner and the lifecycle events that will be triggered on observers between each state transition:
 [[FIle:]]
Summary
This chapter has introduced the basics of lifecycle awareness and the classes and interfaces of the Android Lifecycle package included with Android Jetpack. The package contains a number of classes and interfaces that are used to create lifecycle owners, lifecycle observers and lifecycle-aware components. A lifecycle owner has assigned to it a Lifecycle object that maintains a record of the owners state and a list of subscribed observers. When the owner’s state changes, the observer is notified via lifecycle event methods so that it can respond to the change.
The next chapter will create an Android Studio project that demonstrates how to work with and create lifecycle-aware components including the creation of both lifecycle observers and owners, and the handling of lifecycle state changes and events.