Mobile Development 32 min read

Understanding Android Jetpack Lifecycle: Principles, Usage, and Source Code Analysis

This article introduces Android Jetpack and its Architecture Components, focuses on the Lifecycle library, demonstrates how to integrate it into activities and MVP architectures, explains the underlying source code including ReportFragment and LifecycleRegistry, and provides practical code examples for effective lifecycle management.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Understanding Android Jetpack Lifecycle: Principles, Usage, and Source Code Analysis

1. Android Jetpack Introduction

1.1 What is Jetpack

Official definition: Jetpack is a suite of libraries that helps developers follow best practices, reduce boilerplate code, and write code that runs consistently across Android versions and devices, allowing developers to focus on important logic.

Jetpack is more of a concept and attitude; it is a collection of SDKs and development guidelines recommended by Google, reorganizing the Android ecosystem and defining the future direction of Android development.

Benefits of using Jetpack:

Follow best practices – Jetpack components are built with the latest design patterns and are backward‑compatible, reducing crashes and memory leaks.

Eliminate boilerplate – Jetpack manages tedious tasks such as background work, navigation, and lifecycle handling, letting you concentrate on building great apps.

Reduce inconsistency – The libraries work uniformly across Android versions and devices, lowering complexity.

Jetpack (originally meaning a jet‑backpack) metaphorically lifts Android development to the clouds.

1.2 Jetpack Classification

The components are divided into four areas: Architecture, Foundation, Behavior, and UI. The core of the suite is the Architecture component, formally called Android Architecture Components (AAC), which includes Lifecycle, LiveData, and ViewModel – the best tools for MVVM.

The goal of this article is to master AAC components, understand them deeply, and apply them in MVVM architecture.

We will start the study of Jetpack from the basic Lifecycle component.

2. Lifecycle

Lifecycle helps developers manage the lifecycle of Activities and Fragments and serves as the foundation for LiveData and ViewModel. Below we explain why and how to use Lifecycle.

2.1 Before Lifecycle

The official documentation provides an example of managing a location‑display Activity without Lifecycle:

class
MyLocationListener {
public
MyLocationListener(Context context, Callback callback) {
// ...
}
void
start() {
// connect to system location service
}
void
stop() {
// disconnect system location service
}
}
class
MyActivity
extends
AppCompatActivity {
private
MyLocationListener myLocationListener;
@Override
public
void onCreate(...) {
myLocationListener =
new
MyLocationListener(this, location -> {
// update UI
});
}
@Override
public
void onStart() {
super.onStart();
myLocationListener.start();
// manage other components
}
@Override
public
void onStop() {
super.onStop();
myLocationListener.stop();
// manage other components
}
}

In real applications, many components would be managed inside onStart/onStop, making the code hard to maintain and risking memory leaks when asynchronous callbacks invoke start after the Activity has stopped.

Two main problems:

Large amounts of component‑management code inside lifecycle methods are difficult to maintain.

Cannot guarantee that components will not start after the Activity/Fragment has stopped.

Lifecycle solves these problems with a flexible, isolated approach.

2.2 Using Lifecycle

Lifecycle is a library that includes a Lifecycle class storing the state of a component (Activity or Fragment) and allowing other objects to observe that state.

2.2.1 Adding Dependency

For non‑AndroidX projects:

implementation "android.arch.lifecycle:extensions:1.1.1"

For AndroidX projects (most modern apps):

implementation 'androidx.appcompat:appcompat:1.2.0'

AppCompat already depends on Fragment, which brings in ViewModel, LiveData, and Lifecycle.

If you only need Lifecycle, add:

// root build.gradle
repositories { google() ... }
// app build.gradle
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional modules
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
testImplementation "androidx.arch.core:core-testing:$arch_version"

Usually you also add ViewModel and LiveData together with Lifecycle.

2.2.2 Basic Usage

In an Activity (or Fragment) you obtain the Lifecycle instance via getLifecycle() and add an observer:

public class LifecycleTestActivity extends AppCompatActivity {
    private String TAG = "Lifecycle_Test";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lifecycle_test);
        getLifecycle().addObserver(new MyObserver());
        Log.i(TAG, "onCreate: ");
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }
    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }
}

MyObserver implements LifecycleObserver and uses @OnLifecycleEvent annotations to react to lifecycle changes:

public class MyObserver implements LifecycleObserver {
    private String TAG = "Lifecycle_Test";
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connect() { Log.i(TAG, "connect: "); }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disConnect() { Log.i(TAG, "disConnect: "); }
}

When the Activity moves to RESUME, the connect() method runs; when it moves to PAUSE, disConnect() runs. You can also observe other events such as ON_DESTROY.

2.2.2.2 Using Lifecycle in MVP

In an MVP setup, the Presenter can be the observer:

public class LifecycleTestActivity extends AppCompatActivity implements IView {
    private String TAG = "Lifecycle_Test";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lifecycle_test);
        getLifecycle().addObserver(new MyPresenter(this));
        Log.i(TAG, "onCreate: ");
    }
    // onResume / onPause omitted for brevity
    @Override public void showView() {}
    @Override public void hideView() {}
}

class MyPresenter implements LifecycleObserver {
    private static final String TAG = "Lifecycle_Test";
    private final IView mView;
    MyPresenter(IView view) { mView = view; }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void getDataOnStart(LifecycleOwner owner) {
        Log.i(TAG, "getDataOnStart: ");
        Util.checkUserStatus(result -> {
            if (owner.getLifecycle().getCurrentState().isAtLeast(STARTED)) {
                start();
                mView.showView();
            }
        });
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void hideDataOnStop() {
        Log.i(TAG, "hideDataOnStop: ");
        stop();
        mView.hideView();
    }
}

interface IView { void showView(); void hideView(); }

This arrangement lets the Presenter automatically react to Activity lifecycle changes without manual calls in the Activity.

2.2.3 Custom LifecycleOwner

Any class can become a LifecycleOwner by implementing the interface and providing a LifecycleRegistry:

public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }
    @Override
    protected void onStart() {
        super.onStart();
        lifecycleRegistry.markState(Lifecycle.State.STARTED);
    }
    @NonNull
    @Override
    public Lifecycle getLifecycle() { return lifecycleRegistry; }
}

Observers added to this custom owner will receive lifecycle events just like a regular Activity.

2.3 Application Lifecycle – ProcessLifecycleOwner

ProcessLifecycleOwner provides lifecycle callbacks for the whole application process (foreground/background). After adding the lifecycle‑process dependency, you can register an observer in your Application class:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationLifecycleObserver());
    }
    private static class ApplicationLifecycleObserver implements LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        void onAppForeground() { Log.w(TAG, "app moved to foreground"); }
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        void onAppBackground() { Log.w(TAG, "app moved to background"); }
    }
}

This observer receives ON_START when the first Activity appears and ON_STOP when the last Activity disappears.

3. Source Code Analysis

Lifecycle consists of several key classes: Lifecycle, LifecycleOwner, LifecycleRegistry, ReportFragment, and the reflection‑based observer infrastructure.

3.1 Lifecycle Class

Defines the abstract API for adding/removing observers, querying the current state, and the Event/State enums that map Android lifecycle callbacks to lifecycle states.

3.2 Activity Implements LifecycleOwner

ComponentActivity holds a LifecycleRegistry and returns it from getLifecycle(). The registry’s state is updated in onSaveInstanceState and other lifecycle callbacks via ReportFragment.

3.3 ReportFragment – Dispatching Events

ReportFragment (or ActivityLifecycleCallbacks on API 29+) receives Activity callbacks, translates them into Lifecycle.Event values, and forwards them to the LifecycleRegistry via handleLifecycleEvent(). This decouples lifecycle handling from the Activity code.

3.4 LifecycleRegistry – Event Handling

handleLifecycleEvent() computes the target State, moves the registry to that state, and synchronizes all observers. sync() iterates over observers (stored in a FastSafeIterableMap) and performs forward or backward passes until every observer’s state matches the registry’s state.

3.5 ObserverWithState

Wraps a LifecycleObserver with its current State and a GenericLifecycleObserver implementation. dispatchEvent() updates the observer’s state and calls onStateChanged() on the GenericLifecycleObserver.

3.6 Reflection – Lifecycling.getCallback()

Depending on the observer type, Lifecycling returns a GenericLifecycleObserver. For ordinary Java objects, it creates a ReflectiveGenericLifecycleObserver that uses reflection to find methods annotated with @OnLifecycleEvent.

ReflectiveGenericLifecycleObserver

During construction it caches a CallbackInfo object that maps Lifecycle.Event values to the observer’s annotated methods.

CallbackInfo

Holds two maps: event‑to‑method list and method‑to‑event. invokeCallbacks() executes all methods for the given event and also those annotated with ON_ANY.

MethodReference

Encapsulates a reflected Method and the required call type (no args, LifecycleOwner only, or LifecycleOwner + Event). invokeCallback() invokes the method with the appropriate arguments.

Overall, the flow is: Activity → ReportFragment (or callbacks) → LifecycleRegistry.handleLifecycleEvent() → sync() → ObserverWithState.dispatchEvent() → ReflectiveGenericLifecycleObserver.onStateChanged() → CallbackInfo.invokeCallbacks() → MethodReference.invokeCallback(). This matches the initial intuition about event dispatch.

4. Summary

This article introduced the concept of Android Jetpack and its Architecture Components, focused on the Lifecycle library, demonstrated practical usage in Activities, MVP, and custom owners, and provided an in‑depth source‑code walkthrough of how lifecycle events are dispatched and observed.

Mastering Jetpack’s AAC, especially Lifecycle, is essential for modern Android development and for building robust MVVM architectures.

References:

Lifecycle official documentation

Android Jetpack Architecture Components (3) – Lifecycle source analysis

Mobile DevelopmentAndroidlifecycleArchitecture ComponentsJetpack
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.