Ciclo de vida no Android — Um estudo de caso

Phellipe Silva
Mar 13 · 6 min read

A intenção desse post é compartilhar um estudo de caso de ciclos de vida no Android que vai um pouco além do "hello world". Se você ainda está aprendendo sobre ciclos de vida recomendo ler a documentação oficial do Google:

ou ler a belíssima sequência de posts escritos pelo Jose Alcérreca (The Android Lifecycle cheat sheet — part I, II, III and IV):

Quando estamos aprendendo Android sempre nos deparamos com exemplos bem básicos de ciclo de vida, e eu também achava que entender o básico era suficiente para todos os casos… até eu me deparar com a seguinte situação em uma aplicação:

Fluxo complexo entre activities que envolve ciclo de vida

Nesse exemplo nós temos a seguinte sequência de eventos:

  • #1 Usuário entra na app por uma activity que contém um fragment
  • #2 Usuário navega para segunda activity que também contém um fragment
  • #3 Usuário navega para terceira activity que por sua vez é transparente
  • #4 Usuário muda a orientação da tela na activity transparente
  • #5 Com a tela em landscape o usuário aperta back e volta para a segunda activity
  • #6 Com a tela ainda em landscape o usuário aperta back e volta para a primeira activity
  • #7 Por último, o usuário aperta back e sai da app

Nesse momento parei para pensar… O que acontece com o ciclo de vida de cada activity e fragment durante essa sequencia de eventos? 🤔🤔🤔 Mais especificamente:

  • O que acontece com a primeira activity, que está bem abaixo na stack, quando a gente muda a orientação da tela na terceira activity?
  • O que acontece com a segunda activity quando acontece uma rotação com algo transparente sobre ela?
  • O que acontece com os fragments no meio dessa confusão toda?

Um pouco difícil de visualizar e responder, pelo menos para mim... Então eu criei esse repositório para analisar o caso:

Abaixo estão os resultados do estudo de caso. Para implementar esse fluxo eu utilizei o SDK 28 sem alterar o launch mode de nenhuma activity.

O que acontece com as activities durante o fluxo?

Entra na app

🔴Primeira Activity onCreate(null)
🔴Primeira Activity onStart
🔴Primeira Activity onResume

Navega para segunda activity

🔴Primeira Activity onPause
🔵Segunda Activity onCreate(null)
🔵Segunda Activity onStart
🔵Segunda Activity onResume
🔴Primeira Activity onStop

Navega para activity transparente

🔵Segunda Activity onPause
⚪️Terceira [transparente] Activity onCreate(null)
⚪️Terceira [transparente] Activity onStart
⚪️Terceira [transparente] Activity onResume

Muda orientação da tela

⚪️Terceira [transparente] Activity onPause
⚪️Terceira [transparente] Activity onStop
⚪️Terceira [transparente] Activity onDestroy
⚪️Terceira [transparente] Activity onCreate(bundle)
⚪️Terceira [transparente] Activity onStart
⚪️Terceira [transparente] Activity onRestoreInstanceState(bundle)
⚪️Terceira [transparente] Activity onResume
🔵Segunda Activity onStop
🔵Segunda Activity onDestroy
🔵Segunda Activity onCreate(bundle)
🔵Segunda Activity onStart
🔵Segunda Activity onRestoreInstanceState(bundle)
🔵Segunda Activity onResume
🔵Segunda Activity onPause

Pressiona back e sai da activity transparente

⚪️Terceira [transparente] Activity onPause
🔵Segunda Activity onResume
⚪️Terceira [transparente] Activity onStop
⚪️Terceira [transparente] Activity onDestroy

Pressiona back e sai da segunda activity

🔵Segunda Activity onPause
🔴Primeira Activity onDestroy
🔴Primeira Activity onCreate(bundle)
🔴Primeira Activity onStart
🔴Primeira Activity onRestoreInstanceState(bundle)
🔴Primeira Activity onResume
🔵Segunda Activity onStop
🔵Segunda Activity onDestroy

Pressiona back e sai da app

🔴Primeira Activity onPause
🔴Primeira Activity onStop
🔴Primeira Activity onDestroy

O que acontece com os fragments durante o fluxo?

Entra na app

🔶Primeiro Fragment onAttach
🔶Primeiro Fragment onCreate
🔶Primeiro Fragment onCreateView
🔶Primeiro Fragment onActivityCreated
🔶Primeiro Fragment onStart
🔶Primeiro Fragment onResume

Navega para segunda activity

🔶Primeiro Fragment onPause
🔷Segundo Fragment onAttach
🔷Segundo Fragment onCreate
🔷Segundo Fragment onCreateView
🔷Segundo Fragment onActivityCreated
🔷Segundo Fragment onStart
🔷Segundo Fragment onResume
🔶Primeiro Fragment onStop

Navega para activity transparente

🔷Segundo Fragment onPause

Muda orientação da tela

🔷Segundo Fragment onStop
🔷Segundo Fragment onDestroyView
🔷Segundo Fragment onDestroy
🔷Segundo Fragment onDetach
🔷Segundo Fragment onAttach
🔷Segundo Fragment onCreate
🔷Segundo Fragment onCreateView
🔷Segundo Fragment onActivityCreated
🔷Segundo Fragment onStart
🔷Segundo Fragment onResume
🔷Segundo Fragment onPause

Pressiona back e sai da activity transparente

🔷Segundo Fragment onResume

Pressiona back e sai da segunda activity

🔷Segundo Fragment onPause
🔶Primeiro Fragment onDestroyView
🔶Primeiro Fragment onDestroy
🔶Primeiro Fragment onDetach
🔶Primeiro Fragment onAttach
🔶Primeiro Fragment onCreate
🔶Primeiro Fragment onCreateView
🔶Primeiro Fragment onActivityCreated
🔶Primeiro Fragment onStart
🔶Primeiro Fragment onResume
🔷Segundo Fragment onStop
🔷Segundo Fragment onDestroyView
🔷Segundo Fragment onDestroy
🔷Segundo Fragment onDetach

Pressiona back e sai da app

🔶Primeiro Fragment onPause
🔶Primeiro Fragment onStop
🔶Primeiro Fragment onDestroyView
🔶Primeiro Fragment onDestroy
🔶Primeiro Fragment onDetach

O que acontece com as activities e fragments durante o fluxo?

Entra na app

🔶Primeiro Fragment onAttach
🔶Primeiro Fragment onCreate
🔶Primeiro Fragment onCreateView
🔴Primeira Activity onCreate(null)
🔶Primeiro Fragment onActivityCreated
🔶Primeiro Fragment onStart
🔴Primeira Activity onStart
🔴Primeira Activity onResume
🔶Primeiro Fragment onResume

Navega para segunda activity

🔶Primeiro Fragment onPause
🔴Primeira Activity onPause
🔷Segundo Fragment onAttach
🔷Segundo Fragment onCreate
🔷Segundo Fragment onCreateView
🔵Segunda Activity onCreate(null)
🔷Segundo Fragment onActivityCreated
🔷Segundo Fragment onStart
🔵Segunda Activity onStart
🔵Segunda Activity onResume
🔷Segundo Fragment onResume
🔶Primeiro Fragment onStop
🔴Primeira Activity onStop

Navega para activity transparente

🔷Segundo Fragment onPause
🔵Segunda Activity onPause
⚪️️️Terceira [transparente] Activity onCreate(null)
⚪️Terceira [transparente] Activity onStart
⚪️Terceira [transparente] Activity onResume

Muda orientação da tela

⚪️Terceira [transparente] Activity onPause
⚪️Terceira [transparente] Activity onStop
⚪️Terceira [transparente] Activity onDestroy
⚪️Terceira [transparente] Activity onCreate(bundle)
⚪️Terceira [transparente] Activity onStart
⚪️Terceira [transparente] Activity onRestoreInstanceState(bundle)
⚪️Terceira [transparente] Activity onResume
🔷Segundo Fragment onStop
🔵Segunda Activity onStop
🔷Segundo Fragment onDestroyView
🔷Segundo Fragment onDestroy
🔷Segundo Fragment onDetach
🔵Segunda Activity onDestroy
🔷Segundo Fragment onAttach
🔷Segundo Fragment onCreate
🔷Segundo Fragment onCreateView
🔵Segunda Activity onCreate(bundle)
🔷Segundo Fragment onActivityCreated
🔷Segundo Fragment onStart
🔵Segunda Activity onStart
🔷Segundo Activity onRestoreInstanceState(bundle)
🔵Segunda Activity onResume
🔷Segundo Fragment onResume
🔷Segundo Fragment onPause
🔵Segunda Activity onPause

Pressiona back e sai da activity transparente

⚪️Terceira [transparente] Activity onPause
🔵Segunda Activity onResume
🔷Segundo Fragment onResume
⚪️Terceira [transparente] Activity onStop
⚪️Terceira [transparente] Activity onDestroy

Pressiona back e sai da segunda activity

🔷Segundo Fragment onPause
🔵Segunda Activity onPause
🔶Primeiro Fragment onDestroyView
🔶Primeiro Fragment onDestroy
🔶Primeiro Fragment onDetach
🔴Primeira Activity onDestroy
🔶Primeiro Fragment onAttach
🔶Primeiro Fragment onCreate
🔶Primeiro Fragment onCreateView
🔴Primeira Activity onCreate(bundle)
🔶Primeiro Fragment onActivityCreated
🔶Primeiro Fragment onStart
🔴Primeira Activity onStart
🔴Primeira Activity onRestoreInstanceState(bundle)
🔴Primeira Activity onResume
🔶Primeiro Fragment onResume
🔷Segundo Fragment onStop
🔵Segunda Activity onStop
🔷Segundo Fragment onDestroyView
🔷Segundo Fragment onDestroy
🔷Segundo Fragment onDetach
🔵Segunda Activity onDestroy

Pressiona back e sai da app

🔶Primeiro Fragment onPause
🔴Primeira Activity onPause
🔶Primeiro Fragment onStop
🔴Primeira Activity onStop
🔶Primeiro Fragment onDestroyView
🔶Primeiro Fragment onDestroy
🔶Primeiro Fragment onDetach
🔴Primeira Activity onDestroy

Conclusões obtidas

Através desse estudo de caso, cheguei a conclusões e aprendizados que antes não sabia. Eles são:

#1 Callbacks paralelos

Alguns callbacks do ciclo de vida acontecem paralelamente entre dois ou mais components, sendo assim a ordem de alguns eventos não é garantida.

Ex: Quando navegamos e uma activity aparece sobre a outra.

Ex 2: Activities e fragments sendo inicializados ao mesmo tempo (perceba no exemplo abaixo):

Navegação para segunda activity 👇

Primeiro Fragment onPause
Primeira Activity onPause
Segundo Fragment onAttach
Segundo Fragment onCreate
Segundo Fragment onCreateView
Segunda Activity onCreate(null)
Segundo Fragment onActivityCreated
🔷Segundo Fragment onStart <
🔵Segunda Activity onStart <
🔵Segunda Activity onResume <
🔷Segundo Fragment onResume <
Primeiro Fragment onStop
Primeira Activity onStop

Apesar do fragment ter chamado o onStart() antes da activity, não necessariamente o onResume() do mesmo vai ser chamado antes…

#2 Callbacks em Activities no final stack

Nas mudanças de configuração (rotação da tela). As activities que estão na parte de trás da stack e não estão visíveis não invocam os callbacks de lifecycle imediatamente. Os callbacks só são invocados quando a activity se torna visível.

#3 Curiosidades e informações adicionais

  • Ver sua barra de notificações não chama nenhum callback de ciclo de vida.
  • Existe um architecture component do Google para facilitar o gerenciamento do ciclo de vida da sua aplicação.
  • Definir um launch mode customizado para sua activity pode alterar significativamente o ciclo de vida da sua aplicação.
  • Utilizar retenção de fragments (Retained Fragments) também pode alterar o ciclo de vida de sua aplicação.
  • Se o método finish() for chamado dentro dos callbacks onCreate() ou onStart(). A activity vai pular algumas etapas do ciclo de vida, atenção em relação a isso! ⚠️

Então é isso! Espero ter ajudado de alguma forma com esse conhecimento. Qualquer feedback por favor escrever nos comentários abaixo! 😄

Android Dev BR

Artigos em português sobre Android, curados pela comunidade Android Dev BR. Junte-se a nós: slack.androiddevbr.org.

Phellipe Silva

Written by

Android and test automation lover. Consultant @ThoughtWorks

Android Dev BR

Artigos em português sobre Android, curados pela comunidade Android Dev BR. Junte-se a nós: slack.androiddevbr.org.