Introdução

No último tutorial, você aprendeu sobre os ciclos de vida Activity e Fragment, e explorou os métodos que são chamados quando o estado do ciclo de vida muda em atividades e fragmentos. Neste tutorial, você explora o ciclo de vida da atividade com mais detalhes. Você também aprenderá sobre a biblioteca de ciclo de vida do Android Jetpack, que pode ajudá-lo a gerenciar eventos de ciclo de vida com um código mais organizado e fácil de manter.

O que já deveria saber

O que aprenderá

O que fará

Neste tutorial, você expande o aplicativo DessertClicker do tutorial anterior. Você adiciona um cronômetro de plano de fundo e converte o aplicativo para usar a biblioteca de ciclo de vida do Android.

No tutorial anterior, você aprendeu como observar a atividade e os ciclos de vida do fragmento substituindo vários retornos de chamada do ciclo de vida e registrando quando o sistema invoca esses retornos de chamada. Nesta tarefa, você explorará um exemplo mais complexo de gerenciamento de tarefas de ciclo de vida no aplicativo DessertClicker. Você usa um cronômetro que imprime uma instrução de registro a cada segundo, com a contagem do número de segundos que está em execução.

Etapa 1: Configure o DessertTimer

  1. Abra o aplicativo DessertClicker do último tutorial. (Você pode baixar DessertClickerLogs aqui se não tiver o aplicativo).
  2. Na vista Project, expanda java > com.example.android.dessertclicker e abra DessertTimer.kt. Observe que agora todo o código está comentado, portanto, não é executado como parte do aplicativo.
  3. Selecione todo o código na janela do editor. Selecione Code > Comment with Line Comment ou pressione Control+/ (Command+/ em um Mac). Este comando descomenta todo o código no arquivo. (O Android Studio pode mostrar erros de referência não resolvidos até que você reconstrua o aplicativo).
  4. Observe que a classe DessertTimer inclui startTimer() e stopTimer(), que iniciam e param o cronômetro. Quando startTimer() está em execução, o cronômetro imprime uma mensagem de registro a cada segundo, com a contagem total de segundos em que o tempo está decorrendo. O método stopTimer(), por sua vez, para o cronômetro e as instruções de log.
  1. Abra MainActivity.kt. No topo da classe, logo abaixo da variável dessertsSold, adicione uma variável para o cronômetro:
private lateinit var dessertTimer : DessertTimer;
  1. Role para baixo até onCreate() e crie um objeto DessertTimer, logo após a chamada para setOnClickListener():
dessertTimer = DessertTimer()


Agora que você tem um objeto cronômetro de sobremesa, considere onde você deve iniciar e parar o cronômetro para fazê-lo funcionar only quando a atividade estiver na tela. Você verá algumas opções nas próximas etapas.

Etapa 2: Inicie e pare o cronômetro

O método onStart() é chamado antes que a atividade se torne visível. O método onStop() é chamado depois que a atividade deixa de ser visível. Esses retornos de chamada parecem bons candidatos para quando iniciar e parar o cronômetro.

  1. Na classe MainActivity, inicie o cronômetro no retorno de chamada onStart():
override fun onStart() {
   super.onStart()
   dessertTimer.startTimer()

   Timber.i("onStart called")
}
  1. Pare o cronômetro em onStop():
override fun onStop() {
   super.onStop()
   dessertTimer.stopTimer()

   Timber.i("onStop Called")
}
  1. Compile e execute o aplicativo. No Android Studio, clique no painel Logcat. Na caixa de pesquisa Logcat, digite dessertclicker, que filtrará pelas classes MainActivity e DessertTimer. Observe que, assim que o aplicativo é iniciado, o cronômetro também começa a funcionar imediatamente.
  2. Clique no botão Voltar e observe que o cronômetro para novamente. O cronômetro para, pois a atividade e o cronômetro que ele controla foram destruídos.
  3. Use a tela Recentes para retornar ao aplicativo. Observe no Logcat que o cronômetro reinicia de 0.
  4. Clique no botão Share. Observe no Logcat que o cronômetro ainda está em execução.

  5. Clique no botão Home. Observe no Logcat que o cronômetro para de funcionar.
  6. Use a tela Recentes para retornar ao aplicativo. Observe no Logcat que o cronômetro é iniciado novamente de onde parou.
  7. Em MainActivity, no método onStop(), comente a chamada para stopTimer(). Comentando stopTimer() demonstra o caso em que você inicia uma operação em onStart(), mas se esquece de interrompê-la novamente em onStop().
  8. Compile e execute o aplicativo e clique no botão Home após o cronômetro iniciar. Mesmo que o aplicativo esteja em segundo plano, o cronômetro está funcionando e usando continuamente os recursos do sistema. Mantendo o cronômetro em execução é um vazamento de memória para seu aplicativo e provavelmente não é o comportamento que você deseja.

    O padrão geral é que, quando você configura ou inicia algo em um retorno de chamada, você para ou remove esse item no retorno de chamada correspondente. Dessa forma, você evita que nada esteja em execução quando não for mais necessário.
  1. Remova o comentário da linha em onStop() onde você para o cronômetro.
  2. Recorte e cole a chamada startTimer() de onStart() para onCreate(). Esta mudança demonstra o caso em que você inicializa e inicia um recurso em onCreate(), em vez de usar onCreate() para inicializá-lo e onStart() para iniciá-lo.
  3. Compile e execute o aplicativo. Observe que o cronômetro começa a funcionar, como seria de esperar.
  4. Clique em Home para parar o aplicativo. O cronômetro para de funcionar, como você esperaria.
  5. Use a tela Recentes para retornar ao aplicativo. Observe que o cronômetro not inicia novamente neste caso, pois onCreate() somente é chamado quando o aplicativo é iniciado - não é chamado quando um aplicativo retorna ao primeiro plano.

Pontos principais a serem lembrados:

No aplicativo DessertClicker, é bastante fácil ver que, se você iniciar o cronômetro em onStart(), será necessário interromper o cronômetro em onStop(). Há apenas um cronômetro, portanto, pará-lo não é difícil de lembrar.

Em um aplicativo Android mais complexo, você pode configurar muitos elementos em onStart() ou onCreate() e, em seguida, removê-los todos em onStop() ou onDestroy(). Por exemplo, você pode ter animações, música, sensores ou cronômetros que você precisa para configurar e derrubar, e iniciar e parar. Se você esquecer um, isso leva a erros e dores de cabeça.

A biblioteca de ciclo de vida, que faz parte do Android Jetpack, simplifica essa tarefa. A biblioteca é especialmente útil nos casos em que você precisa rastrear muitas peças móveis, algumas das quais estão em diferentes estados de ciclo de vida. A biblioteca muda a maneira como os ciclos de vida funcionam: Normalmente, a atividade ou fragmento diz a um componente (como DessertTimer) o que fazer quando ocorre um retorno de chamada do ciclo de vida. Mas quando você usa a biblioteca de ciclo de vida, o próprio componente observa as mudanças do ciclo de vida e faz o que é necessário quando essas mudanças acontecem.

Existem três partes principais da biblioteca de ciclo de vida:

Nesta tarefa, você converte o aplicativo DessertClicker para usar a biblioteca de ciclo de vida do Android e aprende como a biblioteca torna o trabalho com a atividade do Android e os ciclos de vida de fragmento mais fáceis de gerenciar.

Etapa 1: Transforme o DessertTimer em um LifecycleObserver

Uma parte importante da biblioteca do ciclo de vida é o conceito de observação do ciclo de vida. A observação permite que as classes (como DessertTimer) saibam sobre a atividade ou ciclo de vida do fragmento, e iniciem e parem em resposta às mudanças nesses estados do ciclo de vida. Com um observador de ciclo de vida, você pode remover a responsabilidade de iniciar e parar objetos dos métodos de atividade e fragmento.

  1. Abra a classe DesertTimer.kt.
  2. Altere a assinatura da classe DessertTimer para ficar assim:
class DessertTimer(lifecycle: Lifecycle) : LifecycleObserver {

Esta nova definição de classe faz duas tarefas:

  1. Abaixo da variável runnable, adicione um bloco init à definição da classe. No bloco init, use o método addObserver() para conectar o objeto de ciclo de vida passado do proprietário (a atividade) a esta classe (o observador).
 init {
   lifecycle.addObserver(this)
}
  1. Anote startTimer() com a anotação @OnLifecycleEvent annotation e use o evento de ciclo de vida ON_START. Todos os eventos de ciclo de vida que seu observador de ciclo de vida pode observar estão na classe Lifecycle.Event.
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startTimer() {
  1. Faça a mesmo para stopTimer(), usando o evento ON_STOP:
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopTimer()

Etapa 2: Modifique MainActivity

Sua classe MainActivity já é um proprietário do ciclo de vida por meio de herança, pois a superclasse FragmentActivity implementa LifecycleOwner. Portanto, não há nada que você precise fazer para tornar sua atividade consciente do ciclo de vida. Tudo o que você precisa fazer é passar o objeto de ciclo de vida da atividade para o construtor DessertTimer.

  1. Abra MainActivity. No método onCreate(), modifique a inicialização de DessertTimer para incluir this.lifecycle:
dessertTimer = DessertTimer(this.lifecycle)

A propriedade lifecycle da atividade contém o objeto Lifecycle que esta atividade possui.

  1. Remova a chamada para startTimer() em onCreate(), e a chamada para stopTimer() em onStop(). Você não precisa mais dizer ao DessertTimer o que fazer na atividade, pois o DessertTimer agora está observando o próprio ciclo de vida e é notificado automaticamente quando o estado do ciclo de vida muda. Tudo o que você faz nesses retornos de chamada agora é registrar uma mensagem.
  2. Compile e execute o aplicativo e abra o Logcat. Observe que o cronômetro começou a funcionar, conforme o esperado.
  3. Clique no botão home para colocar o aplicativo em segundo plano. Observe que o cronômetro parou de funcionar, conforme o esperado.

O que acontecerá com seu aplicativo e seus dados se o Android encerrar o aplicativo enquanto ele estiver em segundo plano? Esse caso complicado é importante entender.

Quando seu aplicativo vai para o segundo plano, ele não é destruído, ele apenas é interrompido e aguarda o retorno do usuário. Mas uma das principais preocupações do sistema operacional Android é manter a atividade que está em primeiro plano funcionando sem problemas. Por exemplo, se o seu usuário estiver usando um aplicativo GPS para ajudá-lo a pegar um ônibus, é importante renderizar esse aplicativo GPS rapidamente e continuar mostrando as direções. É menos importante manter o aplicativo DessertClicker, que o usuário pode não ver por alguns dias, funcionando perfeitamente em segundo plano.

O Android regula os aplicativos em segundo plano para que o aplicativo em primeiro plano possa ser executado sem problemas. Por exemplo, o Android limita a quantidade de processamento que os aplicativos executados em segundo plano podem fazer.

Às vezes, o Android até desliga todo o processo do aplicativo, que inclui todas as atividades associadas ao aplicativo. O Android faz esse tipo de desligamento quando o sistema está estressado e corre o risco de atrasar visualmente, portanto, nenhum retorno de chamada ou código adicional é executado neste ponto. O processo do seu aplicativo é simplesmente encerrado, silenciosamente, em segundo plano. Mas para o usuário, não parece que o aplicativo foi fechado. Quando o usuário navega de volta para um aplicativo que o sistema operacional Android desligou, o Android reinicia esse aplicativo.

Nesta tarefa, você simula um desligamento de processo do Android e examina o que acontece com seu aplicativo quando ele é iniciado novamente.

Etapa 1: Use o adb para simular o desligamento do processo

O Android Debug Bridge (adb) é uma ferramenta de linha de comando que permite enviar instruções para emuladores e dispositivos conectados ao seu computador. Nesta etapa, você usa adb para fechar o processo de seu aplicativo e ver o que acontece quando o Android desliga seu aplicativo.

  1. Compile e execute seu aplicativo. Clique no bolinho algumas vezes.
  2. Pressione o botão Home para colocar seu aplicativo em segundo plano. Seu aplicativo agora está parado e está sujeito a ser fechado se o Android precisar dos recursos que o aplicativo está usando.
  3. No Android Studio, clique na guia Terminal para abrir o terminal de linha de comando.
  4. Digite adb e pressione Return.

    Se você ver muitos resultados que começam com Android Debug Bridge version X.XX.X e terminam com tags to be used by logcat (see logcat — help), está tudo bem. Se, em vez disso, você vir adb: command not found, certifique-se de que o comando adb esteja disponível em seu caminho de execução. Para obter instruções, consulte "Adicionar adb ao caminho de execução" no capítulo Utilitários (em inglês).
  5. Copie e cole este comentário na linha de comando e pressione Return:
adb shell am kill com.example.android.dessertclicker

Este comando diz a todos os dispositivos ou emuladores conectados para interromper o processo com o nome do pacote dessertclicker, mas apenas se o aplicativo estiver em segundo plano. Como seu aplicativo estava em segundo plano, nada é mostrado na tela do dispositivo ou do emulador para indicar que o processo foi interrompido. No Android Studio, clique na guia Run para ver uma mensagem que diz "Aplicativo encerrado". Clique na guia Logcat para ver se o retorno de chamada onDestroy() nunca foi executado — sua atividade simplesmente terminou.

  1. Use a tela Recentes para retornar ao aplicativo. Seu aplicativo aparece em recentes, independentemente de ter sido colocado em segundo plano ou interrompido. Ao usar a tela Recentes para retornar ao aplicativo, a atividade é reiniciada. A atividade passa por todo o conjunto de retornos de chamada do ciclo de vida de inicialização, incluindo onCreate().
  2. Observe que quando o aplicativo é reiniciado, ele zera sua "pontuação" (tanto o número de sobremesas vendidas quanto o total em dólares) para os valores padrão (0). Se o Android desligou seu aplicativo, por que não salvou seu estado?

    Quando o sistema operacional reinicia seu aplicativo, o Android faz o possível para redefinir seu aplicativo ao estado anterior. O Android pega o estado de algumas de suas vistas e o salva em um pacote sempre que você sai da atividade. Alguns exemplos de dados que são salvos automaticamente são o texto em um EditText (desde que tenham um ID definido no layout) e a pilha de retorno de sua atividade.

    No entanto, às vezes o sistema operacional Android não saber sobre todos os seus dados. Por exemplo, se você tiver uma variável personalizada como revenue no aplicativo DessertClicker, o sistema operacional Android não conhece esses dados ou sua importância para sua atividade. Você mesmo precisa adicionar esses dados ao pacote.

Etapa 2: Use onSaveInstanceState() para salvar os dados do pacote

O método onSaveInstanceState() é o retorno de chamada que você usa para salvar quaisquer dados de que possa precisar se o sistema operacional Android destruir seu aplicativo. No diagrama de retorno de chamada do ciclo de vida, onSaveInstanceState() é chamado após a atividade ter sido interrompida. É chamado sempre que seu aplicativo entra em segundo plano.

Pense na chamada onSaveInstanceState() como uma medida de segurança; oferece a chance de salvar uma pequena quantidade de informações em um pacote conforme sua atividade sai do primeiro plano. O sistema salva esses dados agora, pois, se esperasse até desligar o aplicativo, o sistema operacional poderia estar sob pressão de recursos. Salvando os dados todas as vezes garante que os dados atualizados no pacote estejam disponíveis para restauração, se necessário.

  1. Em MainActivity, substitua o retorno de chamada onSaveInstanceState() e adicione uma instrução de registro Timber.
override fun onSaveInstanceState(outState: Bundle) {
   super.onSaveInstanceState(outState)

   Timber.i("onSaveInstanceState Called")
}
  1. Compile e execute o aplicativo e clique no botão Home para colocá-lo em segundo plano. Observe que o retorno de chamada onSaveInstanceState() ocorre logo após onPause() e onStop():
  2. No início do arquivo, logo antes da definição da classe, adicione estas constantes:
const val KEY_REVENUE = "revenue_key"
const val KEY_DESSERT_SOLD = "dessert_sold_key"
const val KEY_TIMER_SECONDS = "timer_seconds_key"

Você usará essas chaves para salvar e recuperar dados do pacote de estado da instância.

  1. Role para baixo até onSaveInstanceState() e observe o parâmetro outState, que é do tipo Bundle.

    Um pacote é uma coleção de pares de valor-chave, onde as chaves são sempre strings. Você pode colocar valores primitivos, como valores int e boolean, no pacote.
    Como o sistema mantém este pacote na RAM, é uma prática recomendada manter os dados no pacote pequenos. O tamanho desse pacote também é limitado, embora o tamanho varie de dispositivo para dispositivo. Geralmente, você deve armazenar bem menos do que 100k, caso contrário, você corre o risco de travar seu aplicativo com o erro TransactionTooLargeException.
  2. Em onSaveInstanceState(), coloque o valor de revenue (um inteiro) no pacote com o método putInt():
outState.putInt(KEY_REVENUE, revenue)

O método putInt() (e métodos semelhantes da classe Bundle como putFloat() e putString() leva dois argumentos: Uma string para a chave (a constante KEY_REVENUE) e o valor real a ser salvo.

  1. Repita o mesmo processo com o número de sobremesas vendidas e o status do cronômetro:
outState.putInt(KEY_DESSERT_SOLD, dessertsSold)
outState.putInt(KEY_TIMER_SECONDS, dessertTimer.secondsCount)

Etapa 3: Use onCreate() para restaurar os dados do pacote

  1. Role para cima até onCreate() e examine a assinatura do método:
override fun onCreate(savedInstanceState: Bundle) {

Observe que onCreate() obtém um Bundle cada vez que é chamado. Quando sua atividade é reiniciada devido a um encerramento de processo, o pacote que você salvou é passado para onCreate(). Se sua atividade estava começando do zero, este pacote em onCreate() é null. Portanto, se o pacote não for null, você sabe que está "recriando" a atividade a partir de um ponto previamente conhecido.

  1. Adicione este código a onCreate(), após a configuração do DessertTimer:
if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
}

O teste para null determina se há dados no pacote ou se o pacote é null, o que por sua vez informa se o aplicativo foi iniciado do zero ou foi reiniciado -criado após um desligamento. Este teste é um padrão comum para restaurar dados do pacote.

Observe que a chave que você usou aqui (KEY_REVENUE) é a mesma chave que você usou para putInt(). Para ter certeza de usar a mesma chave todas as vezes, é uma prática recomendada definir essas chaves como constantes. Você usa getInt() para obter os dados do pacote, assim como usou putInt() para colocar os dados no pacote. O método getInt() leva dois argumentos:

O número inteiro que você obtém do pacote é então atribuído à variável revenue e a IU usará esse valor.

  1. Adicione métodos getInt() para restaurar o número de sobremesas vendidas e o valor do cronômetro:
if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
   dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
   dessertTimer.secondsCount =
       savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
}
  1. Compile e execute o aplicativo. Pressione o bolinho, pelo menos, cinco vezes até que se transforme em um donut. Clique em Home para colocar o aplicativo em segundo plano.
  2. Na guia Terminal do Android Studio, execute adb para desligar o processo do aplicativo.
adb shell am kill com.example.android.dessertclicker
  1. Use a tela Recentes para retornar ao aplicativo. Observe que, desta vez, o aplicativo retorna com os valores corretos de receita e sobremesas vendidas do pacote. Mas observe também que a sobremesa voltou a ser um bolinho. Há mais uma tarefa a fazer para garantir que o aplicativo retorne de um desligamento exatamente da forma como foi deixado.
  2. Em MainActivity, examine o método showCurrentDessert(). Observe que este método determina qual imagem de sobremesa deve ser exibida na atividade com base no número atual de sobremesas vendidas e na lista de sobremesas na variável allDesserts.
for (dessert in allDesserts) {
   if (dessertsSold >= dessert.startProductionAmount) {
       newDessert = dessert
   }
    else break
}

Este método depende do número de sobremesas vendidas para escolher a imagem certa. Portanto, você não precisa fazer nada para armazenar uma referência à imagem no pacote em onSaveInstanceState(). Nesse pacote, você já está armazenando a quantidade de sobremesas vendidas.

  1. Em onCreate(), no bloco que restaura o estado do pacote, chame showCurrentDessert():
 if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
   dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
   dessertTimer.secondsCount = 
      savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
   showCurrentDessert()                   
}
  1. Compile e execute o aplicativo e coloque-o em segundo plano. Use adb para encerrar o processo. Use a tela Recentes para retornar ao aplicativo. Observe agora que os valores das sobremesas contadas, receita total e imagem da sobremesa foram restaurados corretamente.

Há um último caso especial no gerenciamento do ciclo de vida de atividade e fragmento que é importante entender: Como as mudanças na configuração afetam o ciclo de vida de suas atividades e fragmentos.

Uma mudança de configuração ocorre quando o estado do dispositivo muda tão radicalmente que a maneira mais fácil para o sistema resolver a mudança é encerrar e reconstruir a atividade. Por exemplo, se o usuário alterar a linguagem do dispositivo, todo o layout pode precisar ser alterado para acomodar diferentes direções de texto. Se o usuário conectar o dispositivo a um dock ou adicionar um teclado físico, o layout do aplicativo pode precisar tirar proveito de um tamanho de tela ou layout diferente. E se a orientação do dispositivo mudar - se o dispositivo for girado de retrato para paisagem ou vice-versa - o layout pode precisar ser alterado para se ajustar à nova orientação.

Etapa 1: Explore a rotação do dispositivo e os retornos de chamada do ciclo de vida

  1. Compile e execute seu aplicativo e abra o Logcat.
  2. Gire o dispositivo ou emulador para o modo paisagem. Você pode girar o emulador para a esquerda ou direita com os botões de rotação ou com o Control e as teclas de seta (Command e as teclas de seta em um Mac).
  3. Examine a saída no Logcat. Filtre a saída em MainActivity.
    Observe que quando o dispositivo ou emulador gira a tela, o sistema chama todos os retornos de chamada do ciclo de vida para encerrar a atividade. Então, conforme a atividade é recriada, o sistema chama todos os retornos de chamada do ciclo de vida para iniciar a atividade.
  4. Em MainActivity, comente todo o método onSaveInstanceState().
  5. Compile e execute seu aplicativo novamente. Clique no bolinho algumas vezes e gire o dispositivo ou emulador. Desta vez, quando o dispositivo é girado e a atividade é desligada e recriada, a atividade começa com os valores padrão.

    Quando ocorre uma alteração na configuração, o Android usa o mesmo pacote de estado de instância que você aprendeu na tarefa anterior para salvar e restaurar o estado do aplicativo. Como acontece com o desligamento do processo, use onSaveInstanceState() para colocar os dados do seu aplicativo no pacote. Em seguida, restaure os dados em onCreate(), para evitar a perda de dados do estado de atividade se o dispositivo for girado.
  6. Em MainActivity, descomente o método onSaveInstanceState(), execute o aplicativo, clique no bolinho e gire o aplicativo ou dispositivo. Observe que, desta vez, os dados da sobremesa são retidos durante a rotação de atividades.

Projeto Android Studio: DessertClickerFinal

Dicas de ciclo de vida

Biblioteca do ciclo de vida

Para criar uma classe com reconhecimento de ciclo de vida:

Encerramentos do processo e salvando o estado da atividade

Preservando a atividade e o estado do fragmento

Mudanças na configuração

Documentação para desenvolvimento em Android:

De outros:

Esta seção lista as possíveis tarefas de casa para os alunos que estão trabalhando neste tutorial como parte de um curso ministrado por um instrutor.

Altere um aplicativo

Abra o aplicativo DiceRoller na Lição 1. (Você pode baixar o aplicativo aqui se não o tiver). Compile e execute o aplicativo e observe que, se você girar o dispositivo, o valor atual de os dados estão perdidos. Implemente onSaveInstanceState() para reter esse valor no pacote e restaure esse valor em onCreate().

Responda a essas perguntas

Pergunta 1

Seu aplicativo contém uma simulação de física que requer computação pesada para ser exibida. Em seguida, o usuário recebe uma chamada telefônica. Qual dos seguintes é verdadeiro?

Pergunta 2

Qual método de ciclo de vida você deve substituir para pausar a simulação quando o aplicativo não está na tela?

Pergunta 3

Para tornar uma classe ciente do ciclo de vida por meio da biblioteca de ciclo de vida do Android, qual interface a classe deve implementar?

Pergunta 4

Sob quais circunstâncias o método onCreate() em sua atividade recebe um Bundle com dados (ou seja, o Bundle não é null)? Mais de uma resposta pode ser aplicável.

Comece a próxima lição: 05.1: ViewModel e ViewModelFactory

Para obter enlaces para outros tutoriais neste curso, consulte a página de destino dos tutoriais Fundamentos de Android em Kotlin.