Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As atividades são um bloco de construção fundamental de aplicativos Android e podem existir em vários estados diferentes. O ciclo de vida da atividade começa com a instanciação e termina com destruição, e inclui muitos estados no meio. Quando uma atividade altera o estado, o método de evento de ciclo de vida apropriado é chamado, notificando a atividade da alteração de estado iminente e permitindo que ele execute o código para se adaptar a essa alteração. Este artigo examina o ciclo de vida das atividades e explica a responsabilidade que uma atividade tem durante cada uma dessas alterações de estado para fazer parte de um aplicativo confiável e bem comportado.
Visão geral do ciclo de vida da atividade
As atividades são um conceito de programação incomum específico do Android. No desenvolvimento tradicional de aplicativos, geralmente há um método principal estático, que é executado para iniciar o aplicativo. Com o Android, no entanto, as coisas são diferentes; Os aplicativos Android podem ser iniciados por meio de qualquer atividade registrada em um aplicativo. Na prática, a maioria dos aplicativos terá apenas uma atividade específica especificada como o ponto de entrada do aplicativo. No entanto, se um aplicativo falhar ou for encerrado pelo sistema operacional, o sistema operacional poderá tentar reiniciar o aplicativo na última atividade aberta ou em qualquer outro lugar na pilha de atividades anterior. Além disso, o sistema operacional pode pausar as atividades quando elas não estiverem ativas e recuperá-las se estiver com pouca memória. Deve ser feita uma consideração cuidadosa para permitir que o aplicativo restaure corretamente seu estado caso uma atividade seja reiniciada, especialmente se essa atividade depender de dados de atividades anteriores.
O ciclo de vida da atividade é implementado como uma coleção de métodos que o sistema operacional chama em todo o ciclo de vida de uma atividade. Esses métodos permitem que os desenvolvedores implementem a funcionalidade necessária para atender aos requisitos de gerenciamento de recursos e de estado de seus aplicativos.
É extremamente importante que o desenvolvedor de aplicativos analise os requisitos de cada atividade para determinar quais métodos expostos pelo ciclo de vida da atividade precisam ser implementados. A falha em fazer isso pode resultar em instabilidade do aplicativo, travamentos, excesso de uso de recursos e possivelmente até mesmo instabilidade do sistema operacional subjacente.
Este capítulo examina o ciclo de vida da atividade em detalhes, incluindo:
- Status da atividade
- Métodos de ciclo de vida
- Mantendo o estado de um aplicativo
Esta seção também inclui um passo a passo que fornece exemplos práticos de como salvar o estado de maneira eficiente durante o ciclo de vida da Atividade. Ao final deste capítulo, você deve ter uma compreensão do ciclo de vida da atividade e como dar suporte a ele em um aplicativo Android.
Ciclo de vida da atividade
O ciclo de vida da atividade do Android compreende uma coleção de métodos expostos na classe Atividade que fornecem ao desenvolvedor uma estrutura de gerenciamento de recursos. Essa estrutura permite que os desenvolvedores atendam aos requisitos exclusivos de gerenciamento de estado de cada atividade em um aplicativo e lidem corretamente com o gerenciamento de recursos.
Status da atividade
O sistema operacional Android arbitra atividades com base em seu estado. Isso ajuda o Android a identificar atividades que não estão mais em uso, permitindo que o sistema operacional recupere memória e recursos. O diagrama a seguir ilustra os estados pelos quais uma atividade pode passar durante seu tempo de vida:
Esses estados podem ser divididos em quatro grupos principais da seguinte maneira:
Ativo ou em execução – as atividades são consideradas ativas ou em execução se estiverem em primeiro plano, também conhecidas como a parte superior da pilha de atividades. Essa é considerada a atividade de prioridade mais alta no Android e, como tal, só será eliminada pelo sistema operacional em situações extremas, como se a atividade tentar usar mais memória do que está disponível no dispositivo, pois isso poderia fazer com que a interface do usuário ficasse sem resposta.
Pausada – Quando o dispositivo entra em suspensão ou uma atividade ainda está visível, mas parcialmente oculta por uma atividade nova, não completa ou transparente, a atividade é considerada pausada. As atividades pausadas ainda estão ativas, ou seja, mantêm todas as informações de estado e membro e permanecem anexadas ao gerenciador de janelas. Essa é considerada a segunda atividade de prioridade mais alta no Android e, como tal, só será eliminada pelo sistema operacional se a execução dessa atividade atender aos requisitos de recursos necessários para manter a Atividade Ativa/Em Execução estável e responsiva.
Parado/em segundo plano – as atividades que são completamente obscurecidas por outra atividade são consideradas paradas ou em segundo plano. As atividades interrompidas ainda tentam manter suas informações de estado e membro pelo maior tempo possível, mas as atividades interrompidas são consideradas a prioridade mais baixa dos três estados e, como tal, o sistema operacional encerrará as atividades nesse estado primeiro para atender aos requisitos de recursos de atividades de prioridade mais alta.
Reiniciado – É possível que uma atividade que está em qualquer estado, de pausada a parada no seu ciclo de vida, seja removida da memória pelo Android. Se o usuário navegar de volta para a atividade, ela deverá ser reiniciada, restaurada para seu estado salvo anteriormente e exibida ao usuário.
Atividade Re-Creation em resposta a alterações de configuração
Para tornar as coisas mais complicadas, o Android complica ainda mais com algo chamado Alterações de Configuração. As alterações de configuração são ciclos rápidos de destruição/recriação de atividades que ocorrem quando a configuração de uma atividade é alterada, como quando o dispositivo é girado (e a atividade precisa ser recriada no modo paisagem ou retrato), quando o teclado é exibido (e a atividade é apresentada com uma oportunidade de redimensionar-se) ou quando o dispositivo é colocado em um dock, entre outros.
As alterações de configuração ainda causam as mesmas alterações de Estado de Atividade que ocorreriam durante a interrupção e a reinicialização de uma atividade. No entanto, para garantir que um aplicativo se sinta responsivo e tenha um bom desempenho durante as alterações de configuração, é importante que eles sejam tratados o mais rápido possível. Por isso, o Android tem uma API específica que pode ser usada para persistir o estado durante as alterações de configuração. Abordaremos isso posteriormente na seção Gerenciamento de Estado ao Longo do Ciclo de Vida.
Métodos de ciclo de vida da atividade
O SDK do Android e, por extensão, a estrutura Xamarin.Android fornecem um modelo avançado para gerenciar o estado das atividades em um aplicativo. Quando o estado de uma atividade está mudando, a atividade é notificada pelo sistema operacional, que invoca métodos específicos naquela atividade. O diagrama a seguir ilustra estes métodos em relação ao Ciclo de Vida da Atividade:
Como desenvolvedor, você pode lidar com as alterações de estado substituindo esses métodos em uma atividade. No entanto, é importante observar que todos os métodos de ciclo de vida são chamados no thread da interface do usuário e impedirão que o sistema operacional execute a próxima parte do trabalho da interface do usuário, como ocultar a atividade atual, exibir uma nova atividade etc. Dessa forma, o código nesses métodos deve ser o mais breve possível para fazer com que um aplicativo se sinta bem executado. Todas as tarefas de execução prolongada devem ser executadas em um thread em segundo plano.
Vamos examinar cada um desses métodos de ciclo de vida e seu uso:
OnCreate
OnCreate é o primeiro método a ser chamado quando uma atividade é criada.
OnCreate é sempre substituído para realizar as inicializações necessárias durante o início de uma Atividade, como:
- Criando exibições
- Inicializando variáveis
- Associar dados estáticos a listas
OnCreate usa um parâmetro Bundle , que é um dicionário para armazenar e passar informações de estado e objetos entre atividades Se o pacote não for nulo, isso indica que a atividade está sendo reiniciada e deve restaurar seu estado da instância anterior. O código a seguir ilustra como recuperar valores do pacote:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
string intentString;
bool intentBool;
if (bundle != null)
{
intentString = bundle.GetString("myString");
intentBool = bundle.GetBoolean("myBool");
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
}
Depois de OnCreate ser concluído, o Android chamará OnStart.
OnStart
OnStart é sempre chamado pelo sistema após a conclusão de OnCreate. As atividades poderão substituir esse método se precisarem executar tarefas específicas antes que uma atividade fique visível, como atualizar valores atuais de exibições dentro da atividade. O Android chamará OnResume imediatamente após esse método.
OnResume
O sistema chama OnResume quando a Atividade está pronta para começar a interagir com o usuário. As atividades devem substituir esse método para executar tarefas como:
- Aumentando as taxas de quadros (uma tarefa comum no desenvolvimento de jogos)
- Iniciando animações
- Escutando atualizações de GPS
- Exibir quaisquer alertas ou caixas de diálogo relevantes
- Conectar manipuladores de eventos externos
Como exemplo, o snippet de código a seguir mostra como inicializar a câmera:
protected override void OnResume()
{
base.OnResume(); // Always call the superclass first.
if (_camera==null)
{
// Do camera initializations here
}
}
OnResume é importante porque qualquer operação feita em OnPause deve ser desfeita em OnResume, pois é o único método de ciclo de vida garantido a ser executado depois de OnPause quando se traz a atividade de volta à vida.
OnPause
OnPause é chamado quando o sistema está prestes a colocar a atividade em segundo plano ou quando a atividade fica parcialmente obscurecida. As atividades devem substituir esse método se precisarem:
Confirmar alterações não salvas em dados persistentes
Destruir ou limpar outros objetos que consomem recursos
Reduzir gradualmente as taxas de quadros e pausar animações
Cancele o registro de manipuladores de eventos externos ou manipuladores de notificação (ou seja, aqueles que estão vinculados a um serviço). Isso deve ser feito para evitar vazamentos de memória de atividade.
Da mesma forma, se a Atividade tiver exibido diálogos ou alertas, eles deverão ser limpos com o
.Dismiss()método.
Por exemplo, o snippet de código a seguir liberará a câmera, pois a Activity não pode usá-la enquanto estiver pausada.
protected override void OnPause()
{
base.OnPause(); // Always call the superclass first
// Release the camera as other activities might need it
if (_camera != null)
{
_camera.Release();
_camera = null;
}
}
Há dois métodos de ciclo de vida possíveis que serão chamados após OnPause:
-
OnResumeserá chamado se a Atividade deve ser retornada para o primeiro plano. OnStopserá chamado se a Atividade estiver sendo colocada em segundo plano.
OnStop
OnStop é chamado quando a atividade não está mais visível para o usuário. Isso acontece quando ocorre um dos seguintes procedimentos:
- Uma nova atividade está sendo iniciada e está encobrindo essa atividade.
- Uma atividade existente está sendo trazida para o primeiro plano.
- A atividade está sendo destruída.
OnStop nem sempre pode ser chamado em situações de baixa memória, como quando o Android está com falta de recursos e não consegue colocar a atividade corretamente em segundo plano. Por esse motivo, é melhor não depender do fato de OnStop ser chamado ao preparar uma Atividade para destruição. Os próximos métodos de ciclo de vida que podem ser chamados após este serão OnDestroy se a Atividade estiver desaparecendo ou OnRestart se a Atividade estiver voltando a interagir com o usuário.
OnDestroy
OnDestroy é o método final que é chamado em uma instância de atividade antes de ser destruída e completamente removida da memória. Em situações extremas, o Android pode acabar com o processo de aplicativo que está hospedando a Atividade, o que resultará na não invocação de OnDestroy. A maioria das Atividades não implementará esse método porque a maioria dos desligamentos e limpezas foi feita nos métodos OnPause e OnStop. O método OnDestroy normalmente é substituído para limpar tarefas de execução longa que podem vazar recursos. Um exemplo disso pode ser processos em segundo plano que foram iniciados em OnCreate.
Não haverá métodos de ciclo de vida chamados depois que a Atividade tiver sido destruída.
OnRestart
OnRestart é chamado depois que sua atividade foi interrompida, antes de ser iniciada novamente. Um bom exemplo disso seria quando o usuário pressiona o botão página inicial durante uma atividade no aplicativo. Quando isso acontece OnPause e, em seguida OnStop , os métodos são chamados e a Atividade é movida para o segundo plano, mas não é destruída. Se o usuário restaurar o aplicativo usando o gerenciador de tarefas ou um aplicativo semelhante, o Android chamará o OnRestart método da atividade.
Não há diretrizes gerais sobre que tipo de lógica deve ser implementada em OnRestart. Isso ocorre porque OnStart é sempre invocado independentemente de a Atividade estar sendo criada ou reiniciada, portanto, todos os recursos exigidos pela Atividade devem ser inicializados em , em OnStartvez de OnRestart.
O próximo método de ciclo de vida chamado depois OnRestart será OnStart.
Voltar vs. Página Inicial
Muitos dispositivos Android têm dois botões distintos: um botão "Voltar" e um botão "Página Inicial". Um exemplo disso pode ser visto na seguinte captura de tela do Android 4.0.3:
Há uma diferença sutil entre os dois botões, embora eles pareçam ter o mesmo efeito de colocar um aplicativo em segundo plano. Quando um usuário clica no botão Voltar, ele está informando ao Android que ele terminou a atividade. O Android destruirá a Atividade. Por outro lado, quando o usuário clica no botão Página Inicial, a atividade é apenas colocada em segundo plano – o Android não encerrará a atividade.
Gerenciando o estado durante todo o ciclo de vida
Quando uma atividade é interrompida ou destruída, o sistema oferece uma oportunidade para salvar o estado da Atividade para reidratação posterior. Esse estado salvo é chamado de estado de instância. O Android fornece três opções para armazenar o estado da instância durante o ciclo de vida da atividade:
Armazenando valores primitivos em um
Dictionaryconhecido como Bundle que o Android usará para salvar o estado.Criando uma classe personalizada que conterá valores complexos, como bitmaps. O Android usará essa classe personalizada para salvar o estado.
Contornar o ciclo de vida da alteração de configuração e assumir a responsabilidade total pela manutenção do estado na atividade.
Este guia aborda as duas primeiras opções.
Estado do pacote
A opção principal para salvar o estado da instância é usar um objeto de dicionário chave/valor conhecido como um Pacote.
Lembre-se de que, quando uma Activity é criada, o método OnCreate recebe um bundle como parâmetro, e esse bundle pode ser usado para restaurar o estado da instância. Não é recomendável usar um pacote para dados mais complexos que não serão serializados com rapidez ou facilidade em pares chave/valor (como bitmaps); em vez disso, ele deve ser usado para valores simples, como cadeias de caracteres.
Uma atividade fornece métodos para ajudar a salvar e recuperar o estado da instância no Pacote:
OnSaveInstanceState – Isso é invocado pelo Android quando a atividade está sendo destruída. As atividades poderão implementar esse método se precisarem persistir quaisquer itens de estado chave/valor.
OnRestoreInstanceState – Isso é chamado após a conclusão do
OnCreatemétodo e oferece outra oportunidade para uma atividade restaurar seu estado após a conclusão da inicialização.
O diagrama a seguir ilustra como esses métodos são usados:
OnSaveInstanceState
OnSaveInstanceState será chamado à medida que a atividade estiver sendo interrompida. Ele receberá um parâmetro de pacote no qual a Atividade pode armazenar seu estado. Quando um dispositivo sofre uma alteração de configuração, uma Atividade pode usar o Bundle objeto que é passado para preservar o estado da Atividade ao substituir OnSaveInstanceState. Por exemplo, considere o seguinte código:
int c;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
this.SetContentView (Resource.Layout.SimpleStateView);
var output = this.FindViewById<TextView> (Resource.Id.outputText);
if (bundle != null) {
c = bundle.GetInt ("counter", -1);
} else {
c = -1;
}
output.Text = c.ToString ();
var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);
incrementCounter.Click += (s,e) => {
output.Text = (++c).ToString();
};
}
O código acima incrementa um inteiro chamado c quando um botão chamado incrementCounter é clicado, exibindo o resultado em um TextView chamado output. Quando ocorre uma alteração de configuração, por exemplo, quando o dispositivo é girado, o código acima perderia o valor de c porque serianullbundle, conforme mostrado na figura abaixo:
Para preservar o valor c deste exemplo, a Atividade pode substituir OnSaveInstanceState, salvando o valor no pacote, conforme mostrado abaixo:
protected override void OnSaveInstanceState (Bundle outState)
{
outState.PutInt ("counter", c);
base.OnSaveInstanceState (outState);
}
Agora, quando o dispositivo é girado para uma nova orientação, o valor inteiro é salvo no pacote e recuperado com a linha:
c = bundle.GetInt ("counter", -1);
Observação
É importante sempre chamar a implementação base de OnSaveInstanceState para que o estado da hierarquia de exibição também possa ser salvo.
Exibir estado
Substituir OnSaveInstanceState é um mecanismo apropriado para substituir e salvar dados transitórios em uma Atividade entre alterações de orientação, como o contador no exemplo acima. No entanto, a implementação OnSaveInstanceState padrão cuidará de salvar dados transitórios na interface do usuário para cada exibição, desde que cada exibição tenha uma ID atribuída. Por exemplo, digamos que um aplicativo tenha um EditText elemento definido em XML da seguinte maneira:
<EditText android:id="@+id/myText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Como o EditText controle tem uma atribuição id , quando o usuário insere alguns dados e gira o dispositivo, os dados ainda são exibidos, conforme mostrado abaixo:
OnRestoreInstanceState
OnRestoreInstanceState será chamado após OnStart. Ele fornece a uma atividade a oportunidade de restaurar qualquer estado que foi salvo anteriormente em um Pacote durante o OnSaveInstanceState anterior. No entanto, este é o mesmo pacote fornecido para OnCreate.
O código a seguir demonstra como o estado pode ser restaurado em OnRestoreInstanceState:
protected override void OnRestoreInstanceState(Bundle savedState)
{
base.OnRestoreInstanceState(savedState);
var myString = savedState.GetString("myString");
var myBool = savedState.GetBoolean("myBool");
}
Esse método existe para fornecer alguma flexibilidade em torno de quando o estado deve ser restaurado. Às vezes, é mais apropriado aguardar até que todas as inicializações sejam feitas antes de restaurar o estado da instância. Além disso, uma subclasse de uma atividade existente só pode querer restaurar determinados valores do estado da instância. Em muitos casos, não é necessário substituir OnRestoreInstanceState, pois a maioria das atividades pode restaurar o estado usando o pacote fornecido para OnCreate.
Para obter um exemplo de como salvar o estado usando um Bundle, consulte o Passo a passo – salvando o estado da atividade.
Limitações do pacote
Embora OnSaveInstanceState facilite a salvação de dados transitórios, ele tem algumas limitações:
Não é chamado em todos os casos. Por exemplo, pressionar Home ou Voltar para sair de uma atividade não resultará em
OnSaveInstanceStateser chamado.O pacote passado para
OnSaveInstanceStatenão foi projetado para objetos grandes, como imagens. No caso de objetos grandes, salvar o objeto de OnRetainNonConfigurationInstance é preferível, conforme discutido abaixo.Os dados salvos usando o pacote são serializados, o que pode levar a atrasos.
O estado do pacote é útil para dados simples que não usam muita memória, enquanto dados de instância de não-configuração são úteis para dados mais complexos ou dados que custam caros de recuperar, como de uma chamada de serviço Web ou de uma consulta de banco de dados complicada. Os dados da instância que não seja de configuração são salvos em um objeto, conforme necessário. A próxima seção apresenta OnRetainNonConfigurationInstance como uma forma de preservar tipos de dados mais complexos por meio de alterações de configuração.
Persistir dados complexos
Além de persistir dados no pacote, o Android também dá suporte ao salvamento de dados ao substituir OnRetainNonConfigurationInstance e retornar uma instância de um Java.Lang.Object que contém os dados a serem mantidos. Há dois benefícios principais de usar OnRetainNonConfigurationInstance para salvar o estado:
O objeto retornado de
OnRetainNonConfigurationInstancetem um bom desempenho com tipos de dados maiores e mais complexos porque a memória retém o objeto.O
OnRetainNonConfigurationInstancemétodo é chamado sob demanda e somente quando necessário. Isso é mais econômico do que usar um cache manual.
O uso OnRetainNonConfigurationInstance é adequado para cenários em que é caro recuperar os dados várias vezes, como em chamadas de serviço Web. Por exemplo, considere o seguinte código que pesquisa o Twitter:
public class NonConfigInstanceActivity : ListActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SearchTwitter ("xamarin");
}
public void SearchTwitter (string text)
{
string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);
var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
}
void ResponseCallback (IAsyncResult ar)
{
var httpReq = (HttpWebRequest)ar.AsyncState;
using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
ParseResults (httpRes);
}
}
void ParseResults (HttpWebResponse httpRes)
{
var s = httpRes.GetResponseStream ();
var j = (JsonObject)JsonObject.Load (s);
var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();
RunOnUiThread (() => {
PopulateTweetList (results);
});
}
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
}
}
Esse código recupera os resultados da Web formatado como JSON, analisa-os e apresenta os resultados em uma lista, conforme mostrado na captura de tela a seguir:
Quando ocorre uma alteração de configuração - por exemplo, quando um dispositivo é girado - o código repete o processo. Para reutilizar os resultados recuperados originalmente e não causar chamadas de rede desnecessárias e redundantes, podemos usar OnRetainNonconfigurationInstance para salvar os resultados, conforme mostrado abaixo:
public class NonConfigInstanceActivity : ListActivity
{
TweetListWrapper _savedInstance;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;
if (tweetsWrapper != null) {
PopulateTweetList (tweetsWrapper.Tweets);
} else {
SearchTwitter ("xamarin");
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _savedInstance;
}
...
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
_savedInstance = new TweetListWrapper{Tweets=results};
}
}
Agora, quando o dispositivo é girado, os resultados originais são recuperados da propriedade LastNonConfiguartionInstance. Neste exemplo, os resultados consistem em um string[] que contém tweets. Como OnRetainNonConfigurationInstance requer que um Java.Lang.Object seja retornado, o string[] é encapsulado em uma classe que é subclasse de Java.Lang.Object, conforme mostrado abaixo.
class TweetListWrapper : Java.Lang.Object
{
public string[] Tweets { get; set; }
}
Por exemplo, se você tentar usar um TextView como o objeto retornado de OnRetainNonConfigurationInstance a Atividade será vazada, conforme ilustrado pelo código abaixo.
TextView _textView;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tv = LastNonConfigurationInstance as TextViewWrapper;
if(tv != null) {
_textView = tv;
var parent = _textView.Parent as FrameLayout;
parent.RemoveView(_textView);
} else {
_textView = new TextView (this);
_textView.Text = "This will leak.";
}
SetContentView (_textView);
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _textView;
}
Nesta seção, aprendemos como preservar dados de estado simples com os Bundle e persistir dados de tipos mais complexos com OnRetainNonConfigurationInstance.
Resumo
O ciclo de vida da atividade do Android fornece uma estrutura poderosa para o gerenciamento de estado de atividades em um aplicativo, mas pode ser complicado entender e implementar. Este capítulo introduziu os diferentes estados pelos quais uma atividade pode passar durante seu tempo de vida, bem como os métodos de ciclo de vida associados a esses estados. Em seguida, foram fornecidas diretrizes sobre que tipo de lógica deve ser executada em cada um desses métodos.






