LifecycleOwner — що це, інтерфейс Jetpack та підписка на події

Автор: IT Sectr Опубліковано: 2026-03-06 Час читання: 9 хв

LifecycleOwner це ключовий інтерфейс бібліотеки Android Jetpack, який оголошує, що об’єкт має життієвий цикл і надає доступ до нього через метод getLifecycle(). Він становить основу компонентної архітектури сучасних Android-додатків, дозволяючи відокремити логіку життєвого циклу від конкретної реалізації Activity або Fragment. За даними Google I/O 2024, понад 85% нових Android-проектів використовують LifecycleOwner для керування підписками та запобігання витокам пам’яті. Цей інтерфейс є фундаментом для LiveData, ViewModel та інших компонентів Jetpack, забезпечуючи безпечне виконання коду лише коли компонент перебуває в активному стані.

Ключові моменти

  • LifecycleOwner — інтерфейс Jetpack, який надає доступ до об’єкта Lifecycle
  • Реалізовано за замовчуванням в Activity and Fragment from AndroidX AppCompat
  • Дозволяє підписуватися на події через LifecycleObserver та DefaultLifecycleObserver
  • Запобігає витокам пам’яті — спостерігачі автоматично відписуються при знищенні
  • Використовується в ViewModel, LiveData та інших компонентах Jetpack для безпечної роботи

Що таке LifecycleOwner?

LifecycleOwner це інтерфейс з пакета androidx.lifecycle, який містить єдиний метод getLifecycle(), що повертає об’єкт Lifecycle. Цей об’єкт відстежує поточний стан компонента (CREATED, STARTED, RESUMED, DESTROYED) and notifies all subscribed observers when it changes. LifecycleOwner is part of Architecture Components and is included in the lifecycle-runtime library.

The main purpose of the interface is to standardize access to the lifecycle. Before Jetpack, developers manually subscribed in onStart and unsubscribed in onStop, which led to code duplication and errors. LifecycleOwner solves this problem by providing a unified mechanism for all Android components. Instead of explicitly calling lifecycle methods, the developer subscribes to Lifecycle once, and notifications arrive automatically.

The interface is declared in Kotlin as a functional interface with a single abstract method:

kotlin
interface LifecycleOwner {
    val lifecycle: Lifecycle
}

Thanks to the functional nature of the interface, it is easy to implement using a delegate or lambda. This is especially convenient for creating Custom Views and ViewModel classes that need to respond to changes in the host's lifecycle. The Lifecycle object obtained from getLifecycle() provides addObserver and removeObserver methods for managing subscriptions.

Як працює LifecycleOwner

LifecycleOwner works in conjunction with two key classes: Lifecycle and LifecycleObserver. Lifecycle stores the current state of the component as an enum State (INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED) and tracks transitions between them. When the state changes, Lifecycle notifies all registered observers by calling the corresponding annotated methods. This mechanism is called “lifecycle-aware” — code is executed only when the component is in an appropriate state.

The event delivery mechanism is based on the Observer pattern. LifecycleOwner acts as the Observable, and the LifecycleObserver implementation acts as the Observer. When Activity or Fragment changes its state (onCreate → onStart → onResume → onPause → onStop → onDestroy), it notifies Lifecycle through the internal ReportFragment mechanism, which is automatically added to the AndroidX system. The developer does not need to manually call Lifecycle methods — everything happens automatically.

Lifecycle StateEventAndroid Lifecycle Method
INITIALIZEDBefore onCreate
CREATEDON_CREATEonCreate
STARTEDON_STARTonStart
RESUMEDON_RESUMEonResume
STARTEDON_PAUSEonPause
CREATEDON_STOPonStop
DESTROYEDON_DESTROYonDestroy

An important detail: Lifecycle guarantees that ON_STOP and ON_DESTROY events will be delivered even in case of a process crash. This makes LifecycleOwner a reliable tool for releasing critical resources. For regular state preservation, it is recommended to use SavedStateHandle in ViewModel, but LifecycleOwner provides a basic level of safety.

LifecycleObserver та DefaultLifecycleObserver

There are two ways to subscribe to LifecycleOwner events: the classic LifecycleObserver with annotations and the modern DefaultLifecycleObserver with explicit methods. Google has recommended the second approach since 2022, as it provides better type safety and avoids the reflection used in the annotation-based approach. DefaultLifecycleObserver requires Java 8+ or Kotlin and is the preferred choice for new projects.

Example of subscribing via DefaultLifecycleObserver:

kotlin
class MyObserver : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        // Запуск GPS-трекінгу лише коли компонент активний
        startLocationUpdates()
    }

    override fun onStop(owner: LifecycleOwner) {
        // Безпечна зупинка при переході в фоновий режим
        stopLocationUpdates()
    }
}

// Підключення:
lifecycleOwner.lifecycle.addObserver(MyObserver())

Each method of DefaultLifecycleObserver takes a LifecycleOwner as a parameter. This allows the observer to access the context of the executing component without needing to pass it separately. This approach makes the code more modular and testable — the Observer does not depend on the specific implementation of Activity or Fragment but works with the LifecycleOwner abstraction.

Анотаційний підхід LifecycleObserver

The old approach using the @OnLifecycleEvent annotation is still found in legacy projects, but its use is not recommended for new code. The reflection required to process annotations adds overhead and can lead to errors that are not caught at compile time. Google officially advises migrating to DefaultLifecycleObserver.

kotlin
// Застарілий підхід — не рекомендується для нових проектів
class MyLegacyObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart() {
        startLocationUpdates()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
        stopLocationUpdates()
    }
}

The annotation-based approach has a significant drawback: lack of Observer lifetime control. If the developer forgets to unsubscribe the Observer when the LifecycleOwner is destroyed, the Observer object remains in memory until the garbage collector runs. DefaultLifecycleObserver solves this problem — the Observer is bound to the Lifecycle and automatically unsubscribes upon transition to the DESTROYED state.

LifecycleOwner в Activity та Fragment

Since AppCompat 1.1.0 and AndroidX Fragment 1.2.0, all Activities and Fragments that extend AppCompatActivity or Fragment are automatically LifecycleOwners. This means that the getLifecycle() method is available by default, and subscribing to lifecycle events works without additional setup. The developer simply calls lifecycle.addObserver() from anywhere in the Activity or Fragment.

Let’s look at an example of integrating LifecycleOwner into an Activity:

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(LocationObserver(this))
    }
}

In this example, lifecycle is an extension property available thanks to AndroidX Activity. The LocationObserver will automatically receive notifications about the start (ON_START) and stop (ON_STOP) of the Activity. When the screen is rotated, the Observer is notified of ON_DESTROY and then ON_CREATE, allowing configuration changes to be handled correctly without additional code.

LifecycleOwner в Fragment

Fragment implements LifecycleOwner through its interface, and its Lifecycle is tied to the Fragment’s lifecycle, not the parent Activity’s. This is important: the Fragment’s Lifecycle transitions to DESTROYED when the Fragment is removed from the transaction, while the Activity may remain in RESUMED. This distinction allows Observers to subscribe separately to the lifecycle of each component.

kotlin
class MyFragment : Fragment() {
    private val uiStateObserver = UiStateObserver()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        lifecycle.addObserver(uiStateObserver)
    }
}

An important advantage of using LifecycleOwner in Fragment is automatic unsubscription when the Fragment transitions to DESTROYED. This is especially relevant for ViewPager, where Fragments can be created and destroyed dynamically. Manual subscription management in this scenario would be extremely complex and error-prone.

Створення власного LifecycleOwner

The LifecycleOwner interface can be implemented in any class that has a lifecycle. This is useful for Custom Views, Services, and even ViewModel in some architectural solutions. Google provides the helper class LifecycleRegistry, which manages the Lifecycle state and generates events. The developer needs to manually call the appropriate LifecycleRegistry methods when the component’s state changes.

Example of implementing LifecycleOwner in a Custom View:

kotlin
class MyCustomView(
    context: Context,
    attrs: AttributeSet?
) : FrameLayout(context, attrs), LifecycleOwner {

    private val lifecycleRegistry = LifecycleRegistry(this)

    override val lifecycle: Lifecycle
        get() = lifecycleRegistry

    fun onStart() {
        lifecycleRegistry.setCurrentState(Lifecycle.State.STARTED)
    }

    fun onStop() {
        lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED)
    }
}

In this example, LifecycleRegistry acts as the state store. The onStart/onStop methods should be called by the parent component (e.g., Activity) when the Custom View becomes visible or hidden. LifecycleRegistry automatically calculates the necessary events for transitioning between states and notifies all subscribed Observers.

When implementing a custom LifecycleOwner, it is important to follow the rule: the LifecycleRegistry state should be updated last in the corresponding lifecycle method, after all other operations. This ensures that Observers receive notification when the component is already fully ready for the new state. Using LifecycleRegistry.createUnsafe as an alternative is also possible but requires caution with threads.

LifecycleOwner в компонентах Jetpack

LifecycleOwner is the foundation for several key Android Jetpack components. LiveData uses LifecycleOwner to determine the active state and automatically unsubscribe when the component is destroyed. ViewModel does not directly implement LifecycleOwner but can receive Lifecycle through SavedStateHandle. Navigation Component uses LifecycleOwner to manage subscriptions in NavBackStackEntry. Understanding this relationship helps build application architecture on a solid foundation.

LiveData interaction with LifecycleOwner:

kotlin
class ExampleActivity : AppCompatActivity() {
    private val viewModel: ExampleViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.userData.observe(this) { data ->
            // this — LifecycleOwner (Activity)
            // Код виконується лише коли Activity в стані RESUMED
            updateUI(data)
        }
    }
}

LiveData requires a LifecycleOwner in the observe() method because it guarantees that UI updates will only occur in the active state. If the Activity is in the background, LiveData keeps the latest value but does not notify the Observer. Upon returning to RESUMED, the Observer receives the current value without additional network or database requests.

DataBinding also uses LifecycleOwner to bind observable fields to the lifecycle of the Activity or Fragment. This helps avoid memory leaks in the ViewModel + DataBinding combination — all subscriptions are automatically cleared when the LifecycleOwner is destroyed. This approach makes the code declarative and safe.

Найкращі практики

Proper use of LifecycleOwner requires following several key rules. First and most important: always subscribe the Observer in onCreate/onViewCreated, not later. This ensures that the Observer receives the initial Lifecycle state (CREATED after onCreate) and does not miss events. The second rule: use DefaultLifecycleObserver instead of the annotation-based approach for all new projects.

  • Do not store a reference to LifecycleOwner in static fields or singletons — this leaks the entire Activity
  • Check the Lifecycle state via getCurrentState() before performing state-sensitive operations
  • Do not create Observers inside lambdas — each recomposition creates a new object, and old Observers will not be automatically unsubscribed
  • Use repeatOnLifecycle for coroutines — the block starts when entering the specified state and cancels when leaving it
  • Do not call setCurrentState on LifecycleRegistry from a background thread — this violates the single-thread guarantee of the lifecycle

The modern approach to working with coroutines and LifecycleOwner is the repeatOnLifecycle extension:

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.flow.collect { value ->
            updateUI(value)
        }
    }
}

This pattern guarantees that collect on Flow is active only in the STARTED or RESUMED state. When transitioning to STOPPED, the collection is automatically cancelled, and upon returning to STARTED, it restarts. repeatOnLifecycle replaces manual unsubscription from Flow in Fragments and is Google’s recommended approach for working with asynchronous data streams in UI components.

Another important recommendation: do not overuse LifecycleObserver for logic unrelated to the lifecycle. If a component needs to perform an action at a specific state but does not require unsubscription upon destruction, it is better to use explicit method calls in onStart/onStop. LifecycleObserver is justified for long-lived components (LocationListener, SensorManager) where manual subscription management is complex and error-prone.

Часті запитання

Чим LifecycleOwner відрізняється від Lifecycle?

LifecycleOwner is an interface that declares that an object has a lifecycle. Lifecycle is a class that stores the current state and manages Observers. LifecycleOwner provides Lifecycle via getLifecycle().

Чи потрібно вручну відписувати LifecycleObserver?

No, Lifecycle automatically unsubscribes all Observers upon transition to DESTROYED. This is one of the main advantages of LifecycleOwner — the developer does not need to manually call removeObserver in onDestroy.

Як LifecycleOwner працює в Fragment?

Fragment implements LifecycleOwner through the AndroidX fragment interface. Its Lifecycle is tied to the Fragment’s lifecycle separately from the Activity. This allows the Observer to react specifically to Fragment events rather than the parent Activity’s.

Чи можна реалізувати LifecycleOwner в Custom View?

Yes, LifecycleRegistry is used for this purpose. The Custom View must implement the LifecycleOwner interface and manually update the LifecycleRegistry state when visibility changes or when it is attached to a window.

Навіщо мені LifecycleOwner, якщо є CoroutineScope?

LifecycleOwner solves a different problem: managing subscriptions to lifecycle events, not cancelling coroutines. For coroutines, lifecycleScope is used, which automatically cancels launched coroutines when the LifecycleOwner is destroyed.

Підсумок

  • LifecycleOwner — an Android Jetpack interface for accessing the lifecycle via getLifecycle()
  • Implemented by default in AppCompatActivity and Fragment from AndroidX
  • Supports DefaultLifecycleObserver — a modern type-safe subscription method
  • Automatically unsubscribes Observers upon transition to DESTROYED, preventing memory leaks
  • Used in LiveData, DataBinding, and Navigation Component as a lifecycle-aware foundation
  • Allows creating custom LifecycleOwners via LifecycleRegistry for Custom Views and Services
  • Modern alternative — repeatOnLifecycle for coroutines and Flow, replacing manual subscription

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також