LifecycleOwner — é uma interface chave da biblioteca Android Jetpack que declara que um objeto possui um ciclo de vida e fornece acesso a ele através do método getLifecycle(). Ela está na base da arquitetura de componentes de aplicativos Android modernos, permitindo separar a lógica de gerenciamento do ciclo de vida da implementação específica de Activity ou Fragment. De acordo com o Google I/O 2024, mais de 85% dos novos projetos Android usam LifecycleOwner para gerenciar assinaturas e prevenir vazamentos de memória. Esta interface é o fundamento para LiveData, ViewModel e outros componentes do Jetpack, garantindo a execução segura de código apenas no estado ativo do componente.
Principais pontos
LifecycleOwner — é uma interface do pacote androidx.lifecycle que contém um único método getLifecycle(), que retorna um objeto Lifecycle. Este objeto rastreia o estado atual do componente (CREATED, STARTED, RESUMED, DESTROYED) e notifica todos os observadores inscritos quando ele muda. LifecycleOwner faz parte dos Architecture Components e está incluído na biblioteca lifecycle-runtime.
A principal tarefa da interface é padronizar o acesso ao ciclo de vida. Antes do Jetpack, os desenvolvedores usavam inscrição manual em onStart e cancelamento em onStop, o que levava à duplicação de código e erros. LifecycleOwner resolve esse problema fornecendo um mecanismo unificado para todos os componentes Android. Em vez de chamar explicitamente métodos do ciclo de vida, o desenvolvedor se inscreve no Lifecycle uma vez, e as notificações chegam automaticamente.
A interface é declarada em Kotlin como uma interface funcional com um único método abstrato:
interface LifecycleOwner {
val lifecycle: Lifecycle
}
Graças à natureza funcional da interface, ela é fácil de implementar usando um delegado ou lambda. Isso é especialmente conveniente para criar Custom Views e classes ViewModel que devem reagir a mudanças no ciclo de vida do host. O objeto Lifecycle obtido de getLifecycle() fornece os métodos addObserver e removeObserver para gerenciar assinaturas.
LifecycleOwner trabalha em conjunto com duas classes chave: Lifecycle e LifecycleObserver. Lifecycle armazena o estado atual do componente como um enum State (INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED) e rastreia as transições entre eles. Quando o estado muda, Lifecycle notifica todos os observadores registrados, chamando os métodos anotados correspondentes. Este mecanismo é chamado de "lifecycle-aware" — o código é executado apenas quando o componente está em um estado adequado.
O mecanismo de transmissão de eventos é baseado no padrão Observer. LifecycleOwner atua como Observable, e a implementação de LifecycleObserver atua como Observer. Activity ou Fragment, ao mudar seu estado (onCreate → onStart → onResume → onPause → onStop → onDestroy), notifica o Lifecycle através do mecanismo interno ReportFragment, que é adicionado ao sistema AndroidX automaticamente. O desenvolvedor não precisa chamar manualmente os métodos do Lifecycle — tudo acontece automaticamente.
| Estado do Lifecycle | Evento | Método do ciclo de vida Android |
|---|---|---|
| INITIALIZED | — | Antes do onCreate |
| CREATED | ON_CREATE | onCreate |
| STARTED | ON_START | onStart |
| RESUMED | ON_RESUME | onResume |
| STARTED | ON_PAUSE | onPause |
| CREATED | ON_STOP | onStop |
| DESTROYED | ON_DESTROY | onDestroy |
Um detalhe importante: Lifecycle garante que os eventos ON_STOP e ON_DESTROY serão entregues mesmo em caso de falha do processo. Isso torna o LifecycleOwner uma ferramenta confiável para liberar recursos críticos. Para salvamento de estado comum, recomenda-se usar SavedStateHandle no ViewModel, mas o LifecycleOwner fornece um nível básico de segurança.
Existem duas maneiras de se inscrever em eventos do LifecycleOwner: o clássico LifecycleObserver com anotações e o moderno DefaultLifecycleObserver com métodos explícitos. A segunda abordagem é recomendada pelo Google desde 2022, pois oferece melhor segurança de tipos e evita reflexão, que era usada na abordagem de anotações. DefaultLifecycleObserver requer Java 8+ ou Kotlin e é preferível para novos projetos.
Exemplo de inscrição via DefaultLifecycleObserver:
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Iniciar rastreamento GPS apenas quando o componente estiver ativo
startLocationUpdates()
}
override fun onStop(owner: LifecycleOwner) {
// Parada segura ao entrar em modo de segundo plano
stopLocationUpdates()
}
}
// Conexão:
lifecycleOwner.lifecycle.addObserver(MyObserver())
Cada método do DefaultLifecycleObserver recebe LifecycleOwner como parâmetro. Isso permite que o observador acesse o contexto do componente em execução sem precisar passá-lo separadamente. Essa abordagem torna o código mais modular e testável — o Observer não depende da implementação específica de Activity ou Fragment, mas trabalha com a abstração LifecycleOwner.
A maneira antiga usando a anotação @OnLifecycleEvent ainda é encontrada em projetos legados, mas seu uso não é recomendado para código novo. A reflexão necessária para processar anotações adiciona sobrecarga e pode levar a erros que não são detectados em tempo de compilação. O Google oficialmente aconselha migrar para DefaultLifecycleObserver.
// Abordagem obsoleta — não recomendada para novos projetos
class MyLegacyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
startLocationUpdates()
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
stopLocationUpdates()
}
}
A abordagem de anotação tem uma desvantagem significativa: falta de controle sobre o tempo de vida do Observer. Se o desenvolvedor esquecer de cancelar o Observer quando o LifecycleOwner for destruído, o objeto Observer permanecerá na memória até a chamada do coletor de lixo. DefaultLifecycleObserver resolve esse problema — o Observer é vinculado ao Lifecycle e é automaticamente cancelado ao fazer a transição para o estado DESTROYED.
A partir do AppCompat 1.1.0 e AndroidX Fragment 1.2.0, todas as Activities e Fragments que herdam de AppCompatActivity ou Fragment são automaticamente LifecycleOwner. Isso significa que o método getLifecycle() está disponível neles por padrão, e a inscrição em eventos do ciclo de vida funciona sem configuração adicional. O desenvolvedor só precisa chamar lifecycle.addObserver() de qualquer lugar na Activity ou Fragment.
Vamos ver um exemplo de integração do LifecycleOwner em uma Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(LocationObserver(this))
}
}
Neste exemplo, lifecycle é uma extension property disponível graças ao AndroidX Activity. O observer LocationObserver receberá automaticamente notificações sobre o início (ON_START) e parada (ON_STOP) da Activity. Ao girar a tela, o Observer é notificado sobre ON_DESTROY e depois ON_CREATE, o que permite lidar corretamente com mudanças de configuração sem código adicional.
Fragment implementa LifecycleOwner através da interface, e seu Lifecycle está vinculado ao ciclo de vida do Fragment, não da Activity pai. Isso é importante: o Lifecycle do Fragment faz a transição para DESTROYED quando o Fragment é removido da transação, enquanto a Activity pode permanecer em RESUMED. Essa diferença permite que o Observer se inscreva separadamente no ciclo de vida de cada componente.
class MyFragment : Fragment() {
private val uiStateObserver = UiStateObserver()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycle.addObserver(uiStateObserver)
}
}
Uma vantagem importante do uso do LifecycleOwner em Fragment é o cancelamento automático quando o Fragment faz a transição para DESTROYED. Isso é especialmente relevante para ViewPager, onde Fragments podem ser criados e destruídos dinamicamente. O gerenciamento manual de assinaturas nesse cenário seria extremamente complexo e propenso a erros.
A interface LifecycleOwner pode ser implementada em qualquer classe que tenha um ciclo de vida. Isso é útil para Custom Views, Services e até ViewModel em algumas soluções arquiteturais. O Google fornece a classe auxiliar LifecycleRegistry, que gerencia o estado do Lifecycle e gera eventos. O desenvolvedor precisa chamar manualmente os métodos correspondentes do LifecycleRegistry quando o estado do componente muda.
Exemplo de implementação do LifecycleOwner em uma Custom View:
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)
}
}
Neste exemplo, LifecycleRegistry atua como um armazenamento de estado. Os métodos onStart/onStop devem ser chamados pelo componente pai (por exemplo, Activity) quando a Custom View se torna visível ou é ocultada. LifecycleRegistry calcula automaticamente os eventos necessários para a transição entre estados e notifica todos os Observers inscritos.
Ao implementar seu próprio LifecycleOwner, é importante seguir a regra: o estado do LifecycleRegistry deve ser atualizado por último no método correspondente do ciclo de vida, após todas as outras operações. Isso garante que os Observers recebam a notificação quando o componente já estiver completamente pronto para o novo estado. Usar LifecycleRegistry.createUnsafe como alternativa também é possível, mas requer cuidado com threads.
LifecycleOwner é a base para vários componentes chave do Android Jetpack. LiveData usa LifecycleOwner para determinar o estado ativo e cancelar automaticamente a assinatura quando o componente é destruído. ViewModel não implementa LifecycleOwner diretamente, mas pode obter Lifecycle através do SavedStateHandle. Navigation Component usa LifecycleOwner para gerenciar assinaturas no NavBackStackEntry. Entender essa inter-relação ajuda a construir uma arquitetura de aplicativo sobre uma base sólida.
Interação do LiveData com o LifecycleOwner:
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)
// Código executado apenas quando a Activity está no estado RESUMED
updateUI(data)
}
}
}
LiveData requer LifecycleOwner no método observe() porque isso garante que as atualizações da UI ocorrerão apenas no estado ativo. Se a Activity estiver em segundo plano, o LiveData mantém o último valor, mas não notifica o Observer. Ao retornar para RESUMED, o Observer recebe o valor atual sem consultas adicionais à rede ou banco de dados.
DataBinding também usa LifecycleOwner para vincular campos observáveis ao ciclo de vida da Activity ou Fragment. Isso permite evitar vazamentos de memória na combinação ViewModel + DataBinding — todas as assinaturas são automaticamente limpas quando o LifecycleOwner é destruído. Essa abordagem torna o código declarativo e seguro.
O uso correto do LifecycleOwner requer a observância de várias regras chave. A primeira e mais importante: sempre inscreva o Observer em onCreate/onViewCreated, não depois. Isso garante que o Observer receba o estado inicial do Lifecycle (CREATED após onCreate) e não perca eventos. A segunda regra: use DefaultLifecycleObserver em vez da abordagem de anotação para todos os novos projetos.
A abordagem moderna para trabalhar com corrotinas e LifecycleOwner — a extensão repeatOnLifecycle:
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.flow.collect { value ->
updateUI(value)
}
}
}
Esse padrão garante que o collect no Flow esteja ativo apenas no estado STARTED ou RESUMED. Ao fazer a transição para STOPPED, a coleção é automaticamente cancelada, e ao retornar para STARTED, é reiniciada. repeatOnLifecycle substitui o cancelamento manual de assinatura de Flow em Fragment e é a abordagem recomendada pelo Google para trabalhar com fluxos de dados assíncronos em componentes de UI.
Outra recomendação importante: não abuse do LifecycleObserver para lógica não relacionada ao ciclo de vida. Se um componente deve executar uma ação em um estado específico, mas não requer cancelamento ao ser destruído, é melhor usar chamadas explícitas de métodos em onStart/onStop. LifecycleObserver é justificado para componentes de longa duração (LocationListener, SensorManager), onde o gerenciamento manual de assinaturas é complexo e propenso a erros.
Perguntas frequentes
LifecycleOwner — é uma interface que declara que um objeto tem um ciclo de vida. Lifecycle — é uma classe que armazena o estado atual e gerencia os Observers. LifecycleOwner fornece o Lifecycle através de getLifecycle().
Não, Lifecycle cancela automaticamente todos os Observers ao fazer a transição para DESTROYED. Esta é uma das principais vantagens do LifecycleOwner — o desenvolvedor não precisa chamar manualmente removeObserver no onDestroy.
Fragment implementa LifecycleOwner através da interface de fragments AndroidX. Seu Lifecycle está vinculado ao ciclo de vida do Fragment separadamente da Activity. Isso permite que o Observer reaja especificamente aos eventos do Fragment, não da Activity pai.
Sim, para isso é usado LifecycleRegistry. A Custom View deve implementar a interface LifecycleOwner e atualizar manualmente o estado do LifecycleRegistry quando a visibilidade ou a anexação à janela mudar.
LifecycleOwner resolve uma tarefa diferente: gerenciamento de assinaturas de eventos do ciclo de vida, não cancelamento de corrotinas. Para corrotinas, é usado o lifecycleScope, que cancela automaticamente as corrotinas em execução quando o LifecycleOwner é destruído.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também