Neste tutorial, você aprende sobre uma parte fundamental do Android: A atividade e o ciclo de vida do fragmento. O ciclo de vida da atividade é o conjunto de estados em que uma atividade pode estar durante seu tempo de vida. O ciclo de vida se estende desde quando a atividade é inicialmente criada até quando é destruída e o sistema recupera os recursos dessa atividade. À medida que um usuário navega entre as atividades em seu aplicativo (e dentro e fora de seu aplicativo), essas atividades fazem a transição entre diferentes estados no ciclo de vida da atividade.
O ciclo de vida do fragmento é muito semelhante ao das atividades. Este tutorial se concentra principalmente nas atividades, com uma rápida análise dos fragmentos no final.
Como desenvolvedor Android, você precisa entender o ciclo de vida da atividade. Se suas atividades não respondem corretamente às mudanças de estado do ciclo de vida, seu aplicativo pode gerar erros estranhos, comportamento confuso para seus usuários ou usar muitos recursos do sistema Android. Compreendendo o ciclo de vida do Android e responder corretamente às mudanças de estado do ciclo de vida é fundamental para ser um bom cidadão do Android.
onCreate()
da atividade faz e o tipo de operações que são realizadas nesse
método. Activity
e Fragment
, e os retornos de chamadas que
são invocados quando a atividade se move entre estados.Timber
para fazer login em seu aplicativo. Timber
. Neste tutorial, você trabalha com um aplicativo inicial chamado DessertClicker. Nesse aplicativo, cada vez que o usuário toca uma sobremesa na tela, o aplicativo "compra" a sobremesa para o usuário. O aplicativo atualiza os valores no layout para o número de sobremesas que foram compradas e para o valor total gasto pelo usuário.
Este aplicativo contém vários erros relacionados ao ciclo de vida do Android: Por exemplo, em certas circunstâncias, o aplicativo redefine os valores de sobremesa para 0 e continua usando recursos do sistema mesmo quando está em segundo plano. Compreendendo o ciclo de vida do Android ajudará você a entender por que esses problemas acontecem e como corrigi-los.
Cada atividade e cada fragmento tem o que é conhecido como um ciclo de vida. Esta é uma alusão aos ciclos de vida dos animais, como o ciclo de vida desta borboleta - os diferentes estados da borboleta mostram seu crescimento desde o nascimento até a idade adulta formada e até a morte.
Da mesma forma, o ciclo de vida da atividade é formado pelos diferentes estados pelos quais uma atividade pode passar, desde o momento em que a atividade é inicializada pela primeira vez até quando é finalmente destruída e sua memória recuperada pelo sistema. Conforme o usuário inicia seu aplicativo, navega entre as atividades, navega dentro e fora do seu aplicativo e sai dele, a atividade muda de estado. O diagrama abaixo mostra todos os estados do ciclo de vida da atividade. Como seus nomes indicam, esses estados representam o status da atividade.
Frequentemente, você deseja alterar algum comportamento ou executar algum código quando o estado do ciclo de
vida da atividade muda. Portanto, a própria classe Activity
e quaisquer subclasses de
Activity
como AppCompatActivity
implementam um conjunto de métodos de retorno de
chamada do ciclo de vida. O Android invoca esses retornos de chamada quando a atividade muda de um estado
para outro, e você pode substituir esses métodos em suas próprias atividades para realizar tarefas em
resposta a essas mudanças de estado do ciclo de vida. O diagrama a seguir mostra os estados do ciclo de vida
junto com os retornos de chamada substituíveis disponíveis.
Um fragmento também tem um ciclo de vida. O ciclo de vida de um fragmento é semelhante ao ciclo de vida de uma atividade, portanto, muito do que você aprende se aplica a ambos. Neste tutorial, você se concentra no ciclo de vida da atividade, pois é uma parte fundamental do Android e a mais fácil de observar em um aplicativo simples. Aqui está o diagrama correspondente para o ciclo de vida do fragmento:
É importante saber quando esses retornos de chamada são usados e o que fazer em cada método de retorno de chamada. Mas ambos os diagramas são complexos e podem ser confusos. Neste tutorial, em vez de apenas ler o que cada estado e retorno de chamada significa, você fará um trabalho de detetive e desenvolverá sua compreensão do que está acontecendo.
Para descobrir o que está acontecendo com o ciclo de vida do Android, é útil saber quando os vários métodos de ciclo de vida são chamados. Isso ajudará você a descobrir onde algo está dando errado no DessertClicker.
Uma maneira simples de fazer isso é usar a API de registro do Android. O registro permite que você escreva mensagens curtas em um console enquanto o aplicativo é executado e você pode usá-lo para mostrar quando diferentes retornos de chamada são acionados.
MainActivity.kt
e examine o método onCreate()
para esta atividadeoverride fun onCreate(savedInstanceState: Bundle?) {
...
}
No diagrama do ciclo de vida da atividade, você pode ter reconhecido o método onCreate()
, pois
já usou esse retorno de chamada antes. É o único método que toda atividade deve implementar. O método
onCreate()
é onde você deve fazer qualquer inicialização única para sua atividade. Por exemplo,
em onCreate()
você infla o layout, define ouvintes de clique ou configura a vinculação de
dados.
O método de ciclo de vida onCreate()
é chamado uma vez, logo após a atividade ser inicializada
(quando o novo objeto Activity
é criado na memória). Após a execução de
onCreate()
, a atividade é considerada criada.
onCreate()
, logo após a chamada para super.onCreate()
, adicione a
seguinte linha. Importe a classe Log
se necessário. (Pressione Alt+Enter
ou
Option+Enter
em um Mac e selecione Import).Log.i("MainActivity", "onCreate Called")
A classe Log
grava mensagens no Logcat. Existem três partes para este comando:
Log.i()
grava uma mensagem informativa. Outros métodos na classe
Log
incluem Log.e()
para erros ou Log.w()
para avisos."MainActivity"
. A etiqueta é uma string que permite
encontrar mais facilmente suas mensagens de registro no Logcat. A etiqueta é normalmente o nome da
classe. "onCreate called"
.
Log.i()
ou
outros métodos de classe Log
.I/MainActivity
no campo de pesquisa.MainActivity
como a etiqueta de registro em seu
código, você pode usar essa etiqueta para filtrar o registro. Adicione I/
no início
significa que esta é uma mensagem informativa, criada por Log.i()
.com.example.android.dessertclicker
), sua
etiqueta de registro (com I/
no início) e a mensagem real. Como essa mensagem aparece no
log, você sabe que onCreate()
foi executado. O método de ciclo de vida onStart()
é chamado logo após onCreate()
. Depois que
onStart()
for executado, sua atividade ficará visível na tela. Ao contrário de
onCreate()
, que é chamado apenas uma vez para inicializar sua atividade, onStart()
pode ser chamado muitas vezes no ciclo de vida de sua atividade.
Observe que onStart()
está emparelhado com um método de ciclo de vida onStop()
correspondente. Se o usuário iniciar seu aplicativo e depois retornar à tela inicial do dispositivo, a
atividade será interrompida e não estará mais visível na tela.
MainActivity.kt
aberto, selecione Code > Override
Methods ou pressione Control+o
. Uma caixa de diálogo aparecerá com uma lista
enorme de todos os métodos que você pode substituir nesta classe.onStart
para pesquisar o método correto. Para rolar para o próximo item
correspondente, use a seta para baixo. Escolha onStart()
na lista e clique em
OK para inserir o código de substituição padrão. O código é parecido com este:override fun onStart() {
super.onStart()
}
onStart()
, adicione uma mensagem de registro:override fun onStart() {
super.onStart()
Log.i("MainActivity", "onStart Called")
}
I/MainActivity
no campo de pesquisa para filtrar o registro. Observe que os métodos
onCreate()
e onStart()
foram chamados um após o outro e que sua atividade está
visível na tela. onStart()
é
registrado uma segunda vez no Logcat. Observe também que o método onCreate()
geralmente não
é chamado novamente. Nesta tarefa, você modifica seu aplicativo para usar uma biblioteca de registro popular chamada
Timber
. Timber
tem várias vantagens sobre a classe Android Log
embutida. Em particular, a biblioteca Timber
:
Você verá o primeiro benefício imediatamente; os outros você apreciará ao criar e enviar aplicativos maiores.
implementation
. A linha de código será
semelhante a isto, embora o número da versão possa ser diferente. implementation 'com.jakewharton.timber:timber:4.7.1'
dependencies {
...
implementation 'com.jakewharton.timber:timber:4.7.1'
}
Nesta etapa, você cria uma classe Application
. Application
é uma classe base que
contém o estado global do aplicativo para todo o seu aplicativo. É também o principal objeto que o sistema
operacional usa para interagir com seu aplicativo. Há uma classe Application
padrão que o
Android usa se você não especificar uma, então sempre há um objeto Application
criado para seu
aplicativo, sem a necessidade de fazer nada especial para crie-o.
Timber
usa a classe Application
, pois todo o aplicativo usará esta biblioteca de
registro e a biblioteca precisa ser inicializada uma vez, antes de tudo o mais ser configurado. Em casos
como esse, você pode criar uma subclasse da classe Application
e substituir os padrões com sua
própria implementação personalizada.
Depois de criar sua classe Application
, você precisa especificar a classe no manifesto Android.
dessertclicker
, crie uma classe Kotlin chamada ClickerApplication
.
Para fazer isso, expanda app > java e clique com o botão direito em
com.example.android.dessertclicker. Selecione New > Kotlin
File/Class.
O Android Studio cria uma classe ClickerApplication
e a abre no editor de código. O código é
parecido com este:
package com.example.android.dessertclicker
class ClickerApplication {
}
Application
e importe a classe
Application
se necessário.class ClickerApplication : Application() {
onCreate()
, selecione Code > Override Methods
ou pressione Control+o
. class ClickerApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}
onCreate()
, inicialize a biblioteca Timber
:override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
}
Esta linha de código inicializa a biblioteca Timber
para seu aplicativo para que você possa
usar a biblioteca em suas atividades.
<application>
, adicione um novo atributo para a classe
ClickerApplication
, para que o Android saiba usar sua classe Application
do
padrão.<application
android:name=".ClickerApplication"
...
Nesta etapa, você altera suas chamadas Log.i()
para usar Timber
e, em seguida,
implementa o registro para todos os outros métodos de ciclo de vida.
MainActivity
e role até onCreate()
. Substitua Log.i()
por
Timber.i()
e remova a etiqueta de registro.Timber.i("onCreate called")
Como a classe Log
, Timber
também usa o método i()
para mensagens
informativas. Observe que com Timber
você não precisa adicionar uma etiqueta de registro;
Timber
usa automaticamente o nome da classe como a etiqueta de registro.
Log
em onStart()
:override fun onStart() {
super.onStart()
Timber.i("onStart Called")
}
onCreate()
e onStart()
, somente que agora é
Timber
gerando essas mensagens, não Log
. MainActivity
e adicione as
instruções de registro Timber
para cada um. Aqui está o código:override fun onResume() {
super.onResume()
Timber.i("onResume Called")
}
override fun onPause() {
super.onPause()
Timber.i("onPause Called")
}
override fun onStop() {
super.onStop()
Timber.i("onStop Called")
}
override fun onDestroy() {
super.onDestroy()
Timber.i("onDestroy Called")
}
override fun onRestart() {
super.onRestart()
Timber.i("onRestart Called")
}
onCreate()
e onStart()
, há uma mensagem de registro para o retorno de chamada
do ciclo de vida de onResume()
.Quando uma atividade começa do zero, você vê todos os três desses retornos de chamada do ciclo de vida chamados em ordem:
onCreate()
para criar o aplicativo. onStart()
para iniciá-lo e torná-lo visível na tela.onResume()
para dar o foco à atividade e torná-la pronta para o usuário interagir com ela.
Apesar do nome, o método onResume()
é chamado na inicialização, mesmo que não haja nada para
retomar.
Agora que o aplicativo DessertClicker está configurado para registro, você está pronto para começar a usar o aplicativo de várias maneiras e para explorar como os retornos de chamada do ciclo de vida são acionados em resposta a esses usos.
Você começa com o caso de uso mais básico, que é iniciar seu aplicativo pela primeira vez e, em seguida, fecha o aplicativo completamente.
onCreate()
, onStart()
e onResume()
são
chamados quando a atividade começa pela primeira vez.onPause()
,
onStop()
e onDestroy()
são chamados, nessa ordem.onDestroy()
significa
que a atividade foi encerrada e pode ser coletada como lixo. Coleta de
lixo refere-se à limpeza automática de objetos que você não usará mais. Depois que
onDestroy()
é chamado, o sistema operacional sabe que esses recursos são descartáveis e
começa a limpar a memória.finish()
da atividade ou se o usuário forçar o encerramento do
aplicativo. (Por exemplo, o usuário pode forçar o encerramento do aplicativo na tela recente clicando no
X no canto da janela). O sistema Android também pode desligar sua atividade por conta
própria se o seu aplicativo não aparece na tela há muito tempo. O Android faz isso para economizar
bateria e permitir que os recursos do seu aplicativo sejam usados por outros aplicativos. onCreate()
,
onStart()
e onResume()
. Observe que nenhuma das estatísticas do DessertClicker
da atividade anterior foi retida. onCreate()
e
onDestroy()
são chamados apenas uma vez durante o tempo de vida de uma única instância de
atividade: onCreate()
para inicializar o aplicativo pela primeira vez e
onDestroy()
para limpar os recursos usados por seu aplicativo.onCreate()
método é uma etapa importante; é para onde vai toda a sua primeira inicialização,
onde você configura o layout pela primeira vez, inflando-o, e onde você inicializa suas variáveis.Agora que você iniciou o aplicativo e o fechou completamente, viu a maioria dos estados do ciclo de vida para quando a atividade é criada pela primeira vez. Você também viu todos os estados de ciclo de vida pelos quais a atividade passa quando é desligada e destruída. Mas, à medida que os usuários interagem com seus dispositivos com Android, eles alternam entre aplicativos, voltam para casa, iniciam novos aplicativos e tratam com interrupções por outras atividades, como vinculações.
Sua atividade não fecha sempre que o usuário sai dessa atividade:
Quando seu aplicativo está em segundo plano, ele não deve estar em execução ativa para preservar os recursos
do sistema e a vida útil da bateria. Você usa o ciclo de vida Activity
e seus retornos de
chamada para saber quando seu aplicativo está se movendo para o segundo plano, para que você possa pausar
qualquer operação em andamento. Em seguida, você reinicia as operações quando seu aplicativo entra em
primeiro plano.
Por exemplo, considere um aplicativo que executa uma simulação de física. São necessários muitos cálculos, processados na CPU do seu dispositivo, para decidir onde todos os objetos em sua simulação devem estar e para exibi-los. Se um telefonema interromper a simulação, o usuário pode ficar confuso ou até chateado ao voltar ao aplicativo e ver que a simulação foi concluída.
Há também um motivo de desempenho para isso. Digamos que o usuário tenha aberto 20 aplicativos que usam simulações de física com uso intensivo de CPU. Se as atividades desses aplicativos não estiverem na tela, mas ainda estiverem fazendo cálculos pesados de renderização em segundo plano, isso diminuirá o desempenho de todo o telefone.
Nesta etapa, você observa o ciclo de vida da atividade quando o aplicativo entra em segundo plano e retorna novamente ao primeiro plano.
onPause()
e onStop()
são chamados, mas onDestroy()
não.onPause()
é
chamado, o aplicativo não tem mais o foco. Depois de onStop()
, o aplicativo não está mais
visível na tela. Embora a atividade tenha sido interrompida, o objeto Activity
ainda está na
memória, em segundo plano. A atividade não foi destruída. O usuário pode retornar ao aplicativo, então o
Android mantém seus recursos de atividade por perto.onRestart()
e onStart()
e então retomada com onResume()
.onCreate()
não é chamado novamente. O objeto de atividade não foi destruído,
portanto, não precisa ser criado novamente. Em vez de onCreate()
, o método
onRestart()
é chamado. Observe que, desta vez, quando a atividade retorna ao primeiro plano,
o número de Desserts Sold é mantido. onPause()
e onStop()
são
chamados quando o aplicativo entra em segundo plano e, em seguida, onRestart()
,
onStart()
e onResume()
quando ele voltar. onStart()
e onStop()
são chamados várias vezes enquanto o usuário navega de e
para a atividade. Você deve substituir esses métodos para interromper o aplicativo quando ele for movido
para o segundo plano ou iniciá-lo novamente quando ele retornar ao primeiro plano.onRestart()
? O método onRestart()
é muito parecido com onCreate()
.
onCreate()
ou onRestart()
é chamado antes que a atividade se torne visível. O
método onCreate()
é chamado apenas na primeira vez, e onRestart()
é chamado
depois disso. O método onRestart()
é um local para colocar o código que você somente deseja
chamar se sua atividade not for iniciada pela primeira vez.Você aprendeu que quando um aplicativo é iniciado e onStart()
é chamado, o aplicativo se torna
visível na tela. Quando o aplicativo é reiniciado e onResume()
é chamado, o aplicativo ganha o
foco do usuário. A parte do ciclo de vida em que o aplicativo está na tela e tem o foco do usuário é chamada
de ciclo de vida interativo.
Quando o aplicativo vai para o segundo plano, o foco é perdido após onPause()
e o aplicativo
não fica mais visível após onStop()
.
A diferença entre foco e visibilidade é importante, pois é possível que uma atividade seja parcialmente visível na tela, mas não tenha o foco do usuário. Nesta etapa, você vê um caso em que uma atividade é parcialmente visível, mas não tem o foco do usuário.
onPause()
foi chamado.onStop()
não é chamado, pois a atividade ainda está parcialmente visível. Mas a atividade
não tem foco no usuário, e o usuário não pode interagir com ela. A atividade de "compartilhamento" que
está em primeiro plano tem o foco do usuário.onStop()
. Se você quiser que a simulação pare quando a
atividade estiver parcialmente obscurecida, você deve colocar o código para parar a simulação em
onPause()
.onPause()
bloqueia a exibição de
outros, portanto, mantenha o código onPause()
leve. Por exemplo, se uma chamada telefônica
for recebida, o código em onPause()
pode atrasar a notificação da chamada recebida.onResume()
é chamado.onResume()
e onPause()
tem a
ver com foco. O método onResume()
é chamado quando a atividade tem foco, e
onPause()
é chamado quando a atividade perde o foco.O ciclo de vida do fragmento do Android é semelhante ao ciclo de vida da atividade, além de vários métodos específicos do fragmento.
Nesta tarefa, você examina o aplicativo AndroidTrivia que construiu nos tutoriais anteriores e adiciona algum registro para explorar o ciclo de vida do fragmento. O aplicativo AndroidTrivia permite responder a perguntas sobre o desenvolvimento do Android; se você responder três em uma linha corretamente, você ganha o jogo.
Cada tela no aplicativo AndroidTrivia é um Fragment
.
Para manter tudo simples, você usa a API de registro do Android nesta tarefa, em vez da biblioteca Timber.
TitleFragment.kt
. Observe que o Android Studio pode mostrar erros de
vinculação e erros de referência não resolvidos até que você reconstrua o aplicativo.onCreateView()
. Observe que é aqui que o layout do fragmento é
inflado e ocorre a vinculação de dados.onCreateView()
, entre a linha
setHasOptionsMenu()
e a chamada final para retornar: setHasOptionsMenu(true)
Log.i("TitleFragment", "onCreateView called")
return binding.root
onCreateView()
, adicione instruções de registro para cada um dos
métodos de ciclo de vida do fragmento restantes. Aqui está o código: override fun onAttach(context: Context?) {
super.onAttach(context)
Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i("TitleFragment", "onCreate called")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.i("TitleFragment", "onActivityCreated called")
}
override fun onStart() {
super.onStart()
Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
super.onResume()
Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
super.onPause()
Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
super.onStop()
Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
super.onDestroyView()
Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
super.onDetach()
Log.i("TitleFragment", "onDetach called")
}
I/TitleFragment
no campo de pesquisa para filtrar o registro. Quando o aplicativo é
iniciado, o Logcat se parece com a seguinte captura de tela:Aqui você pode ver todo o ciclo de vida de inicialização do fragmento, incluindo estes retornos de chamada:
onAttach()
: Chamado quando o fragmento está associado à atividade de seu proprietário.onCreate()
: Da mesma forma que onCreate()
para a atividade,
onCreate()
para o fragmento é chamado para fazer a criação inicial do fragmento (diferente
layout).onCreateView()
: Chamado para inflar o layout do fragmento. onActivityCreated()
: Chamado quando a atividade do proprietário onCreate()
é
concluída. Seu fragmento não será capaz de acessar a atividade até que este método seja chamado.onStart()
: Chamado quando o fragmento se torna visível; paralelo ao onStart()
da atividade. onResume()
: Chamado quando o fragmento ganha o foco do usuário; paralelo ao
onResume()
da atividade. Abrindo o próximo fragmento faz com que o fragmento do título seja fechado e estes métodos de ciclo de vida sejam chamados:
onPause()
: Chamado quando o fragmento perde o foco do usuário; paralelo ao
onPause()
da atividade.onStop()
: Chamado quando o fragmento não está mais visível na tela; paralelo ao
onStop()
da atividade.onDestroyView()
: Chamado quando a vista do fragmento não é mais necessária, para limpar os
recursos associados a essa vista. onAttach()
e onCreate()
provavelmente não são chamados para iniciar o
fragmento. O objeto de fragmento ainda existe e ainda está anexado à atividade de seu proprietário, então
o ciclo de vida começa novamente com onCreateView()
. onPause()
e
onStop()
são chamados. Este é o mesmo comportamento da atividade: Voltar para casa coloca a
atividade e o fragmento em segundo plano. onStart()
e onResume()
são chamados para retornar o fragmento ao primeiro
plano.Projeto Android Studio: DessertClickerLogs
Activity
. Existem sete métodos de ciclo de vida:onCreate()
onStart()
onPause()
onRestart()
onResume()
onStop()
onDestroy()
Control+o
.Log
, permite que você escreva
mensagens curtas que são exibidas no Logcat dentro do Android Studio.Log.i()
para escrever uma mensagem informativa. Este método leva dois argumentos: A
etiqueta do log, normalmente o nome da classe, e a mensagem do log, uma string curta.
Timber
é uma biblioteca de
registro com várias vantagens sobre a API de registro do Android. Em particular, a biblioteca
Timber
:
Para usar Timber
, adicione sua dependência ao arquivo Gradle e estenda a classe Application
para inicializá-lo:
Application
é uma classe base que contém o estado global do aplicativo para todo o seu
aplicativo. Existe uma classe Application
padrão que é usada pelo Android se você não
especificar uma. Você pode criar sua própria subclasse Application
para inicializar
bibliotecas de todo o aplicativo, como Timber
. Application
personalizada ao seu aplicativo adicionando o atributo
android:name
ao elemento <application>
no manifesto Android. Não se
esqueça de fazer isso!Timber.i()
para escrever mensagens de registro com Timber
. Este método
leva apenas um argumento: A mensagem a ser escrita. A etiqueta de registro (o nome da classe) é
adicionada automaticamente. Documentação para desenvolvimento em Android:
Activity
(referência de API)Fragment
(referência de API)Log
(referência de API)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.
Abra o aplicativo DiceRoller na Lição 1. (Você pode baixar o aplicativo DiceRoller aqui se não tiver o aplicativo). Adicione suporte de Timber a esse aplicativo, usando o mesmo processo que você fez para o aplicativo DessertClicker . Substitua todos os retornos de chamada do ciclo de vida e adicione mensagens de registro para cada retorno de chamada.
Qual dos seguintes NÃO é um estado de ciclo de vida de atividade?
Qual método de ciclo de vida é chamado para tornar uma atividade visível?
onPause()
onVisible()
onStart()
onDestroy()
Qual método de ciclo de vida é chamado para dar um foco de atividade?
onResume()
onVisible()
onStart()
onFocus()
Quando onCreate()
é chamado em uma atividade?
Verifique se o aplicativo tem o seguinte:
Timber
no arquivo build.gradle
para o aplicativo.Application
que inicializa Timber
em
onCreate()
.MainActivity
todos os métodos de retorno de chamada do ciclo de vida,
com chamadas para Timber.i()
para registro. Comece a próxima lição:
Para obter enlaces para outros tutoriais neste curso, consulte a página de destino dos tutoriais Fundamentos de Android em Kotlin.