Blog: Android

Conceitos do ciclo de Vida da Atividade Android

Para navegar entre as fases do ciclo de vida da atividade, a classe “Activity” fornece um conjunto principal de seis callbacks: onCreate(), onStart(), onResume(), onPause(), onStop() e onDestroy(). Conforme a atividade entra em um novo estado, o sistema invoca cada um desses callbacks.

À medida que o usuário começa a sair da atividade, o sistema chama métodos para eliminá-la. Em alguns casos, essa eliminação é somente parcial. A atividade ainda reside na memória, como quando o usuário alterna para outro aplicativo, e ainda pode voltar ao primeiro plano. Se o usuário retornar a essa atividade, a atividade será retomada de onde o usuário parou. Com algumas exceções, os aplicativos são impedidos de iniciar atividades quando executados em segundo plano.

A probabilidade do sistema eliminar um determinado processo, com as atividades nele, depende do estado da atividade no momento. Em Estado da atividade e ejeção da memória, há mais informações sobre o relacionamento entre o estado e a vulnerabilidade para ejeção.

Dependendo da complexidade de sua atividade, não é necessário implementar todos os métodos do ciclo de vida. No entanto, é importante compreender cada um deles e implementar somente os que garantem que o aplicativo tenha o desempenho esperado pelo usuário.

Image

Os callbacks usados para processar as transições entre os estados.

Callbacks do ciclo de vida Esta seção fornece informações conceituais e de implementação sobre os métodos de callback usados durante o ciclo de vida da atividade.

Algumas ações, como chamar setContentView(), fazem parte dos métodos do ciclo de vida da atividade em si. No entanto, o código que implementa as ações de um componente dependente deve ser colocado no próprio componente. Para fazer isso, você precisa tornar o componente dependente ciente do ciclo de vida. Veja Como gerenciar ciclos de vida com componentes que os reconhecem para saber como tornar seus componentes dependentes cientes do ciclo de vida.

onCreate() Esse callback precisa ser implementado. Ele é acionado assim que o sistema cria a atividade. Quando a atividade é criada, ela insere o estado Criado. No método onCreate(), você executa a lógica básica de inicialização do aplicativo. Isso deve acontecer somente uma vez durante todo o período que a atividade durar. Por exemplo, sua implementação de onCreate() pode vincular dados a listas, associar a atividade a um ViewModel e instanciar algumas variáveis com escopo de classe. Esse método recebe o parâmetro savedInstanceState, um objeto Bundle que contém o estado anteriormente salvo da atividade. Se a atividade nunca existiu, o valor do objeto Bundle será nulo.

Caso você tenha um componente ciente do ciclo de vida conectado ao ciclo de vida da sua atividade, ele receberá o evento ON_CREATE. O método anotado com @OnLifecycleEvent será chamado para que seu componente ciente do ciclo de vida possa executar qualquer código de configuração necessário para o estado criado.

onStart() Quando a atividade insere o estado "Iniciado", o sistema invoca esse callback. A chamada onStart() torna a atividade visível ao usuário, à medida que o aplicativo prepara a atividade para inserir o primeiro plano e se tornar interativa. Por exemplo, é nesse método que o aplicativo inicializa o código que mantém a IU.

Quando a atividade é movida para o estado "Iniciado", qualquer componente ciente do ciclo de vida que esteja ligado ao ciclo de vida da atividade receberá o evento ON_START.

O método onStart() faz a conclusão muito rapidamente e, como no caso do estado "Criado", a atividade não reside no estado "Iniciado". Quando a finalização é feita pelo callback, a atividade insere o estado Retomado e o sistema invoca o método onResume().

onResume() Quando a atividade insere o estado "Retomado", ela vem para o primeiro plano e o sistema invoca o callback onResume(). É nesse estado que o aplicativo interage com o usuário. O app permanece nesse estado até que algo afete o foco do app. Esse evento pode ser, por exemplo, receber uma chamada telefônica, navegar pelo usuário para outra atividade ou desativar a tela do dispositivo.

Quando a atividade é movida para o estado "Retomado", qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_RESUME. É nesse momento que os componentes do ciclo de vida podem ativar qualquer funcionalidade que precise operar enquanto o componente estiver visível e em primeiro plano, como o início da visualização da câmera.

Quando ocorre um evento de interrupção, a atividade insere o estado Pausado e o sistema invoca o callback onPause().

Caso a atividade retorne do estado "Pausado" para o estado "Retomado", o sistema chamará novamente o método onResume(). Dessa forma, implemente o onResume() para inicializar os componentes liberados durante onPause() e execute outras inicializações que devem ocorrer sempre que a atividade entrar no estado "Retomado".

Independentemente de qual evento de construção você escolher para executar uma operação de inicialização, certifique-se de usar o evento de ciclo de vida correspondente para liberar o recurso. Se você inicializar algo após o evento ON_START, libere ou finalize esse item após o evento ON_STOP. Caso você inicialize após o evento ON_RESUME, faça a liberação após o evento ON_PAUSE.

onPause() O sistema chama esse método como a primeira indicação de que o usuário está deixando sua atividade, embora nem sempre signifique que a atividade esteja sendo destruída. Isso indica que a atividade não está mais em primeiro plano, embora ainda possa estar visível se o usuário estiver no modo de várias janelas. Use o método onPause() para pausar ou ajustar operações que não devem continuar (ou que precisem continuar com moderação) enquanto a Activity estiver no modo "Pausado" e aquelas que você espera retomar em breve. Há vários motivos pelos quais uma atividade pode entrar nesse estado. Por exemplo:

Algum evento interromper a execução do aplicativo, conforme descrito na seção onResume(). Esse é o caso mais comum. No Android 7.0 (API de nível 24) ou mais recentes, diversos aplicativos operam no modo de várias janelas. Como só um dos aplicativos (janelas) tem foco a qualquer momento, o sistema pausa todos os outros aplicativos. Uma nova atividade semitransparente (como uma caixa de diálogo) é aberta. Enquanto a atividade estiver parcialmente visível, mas não for a atividade em foco, ela permanecerá pausada. Quando a atividade é movida para o estado pausado, qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_PAUSE. É nesse momento que os componentes do ciclo de vida podem interromper qualquer funcionalidade que não precise operar enquanto o componente não estiver em primeiro plano, como na pausa de uma visualização da câmera.

Também é possível usar o método onPause() para liberar recursos do sistema, tratamento de sensores (como GPS) ou quaisquer recursos que possam afetar a duração da bateria enquanto a atividade estiver pausada e o usuário não precisar deles. No entanto, como mencionado acima, na seção onResume(), uma atividade pausada ainda poderá ser completamente visível no modo de várias janelas. Assim, considere usar onStop() em vez de onPause() para liberar ou ajustar completamente operações e recursos relacionados à IU para melhorar o suporte do modo de várias janelas.

A conclusão do método onPause() não significa que a atividade saia do estado "Pausado". Na verdade, a atividade permanece nesse estado até que ela seja retomada ou fique completamente invisível para o usuário. Se a atividade for retomada, o sistema invocará mais uma vez o callback onResume(). Caso a atividade retorne do estado "Pausado" para o estado "Retomado", o sistema manterá a instância Activity residente na memória, chamando novamente a instância quando o sistema invocar onResume(). Nesse cenário, não é necessário reiniciar componentes criados durante qualquer método de callback que leve ao estado "Retomado". Se a atividade ficar completamente invisível, o sistema chamará onStop(). A próxima seção discutirá o callback onStop().

onStop() Quando a atividade não estiver mais visível ao usuário, ela inserirá o estado Interrompido e o sistema invocará o callback onStop(). Isso pode ocorrer, por exemplo, quando uma atividade recém-iniciada preenche toda a tela. O sistema também poderá chamar onStop() quando a atividade parar de operar e estiver prestes a ser concluída.

Quando a atividade é movida para o estado interrompido, qualquer componente ciente do ciclo de vida ligado ao ciclo de vida da atividade receberá o evento ON_STOP. É nesse momento que os componentes do ciclo de vida podem interromper qualquer funcionalidade que não precise operar enquanto o componente não estiver visível na tela.

No método onStop(), o aplicativo liberará ou ajustará recursos desnecessários enquanto o aplicativo não estiver visível ao usuário. Por exemplo, o aplicativo poderá pausar animações ou alternar de atualizações de local mais específicas para as menos detalhadas. O uso de onStop() em vez de onPause() garante que o trabalho relacionado à IU continue, mesmo quando o usuário estiver visualizando a atividade no modo de várias janelas.

Use onStop() também para realizar operações de desligamento de uso intensivo da CPU. Por exemplo, se você não encontrar um momento mais oportuno para salvar informações em um banco de dados, poderá fazer isso durante onStop().

Fonte(s): Google Android Developers

Ciclo de vida da atividade Android

Pode parecer estranho, mas a forma que eu posto conteúdo não segue a ordem lógica do aprendizado, aviso caso não esteja acostumado com meus posts ;)

A ideia aqui e falar um pouco sobre o ciclo de vida da atividade do Android. Nada que você não encontre igual na documentação do Android.

Conforme o usuário navega pelo aplicativo, sai dele e retorna a ele, as instâncias Activity no aplicativo transitam entre diferentes estados no ciclo de vida.

A classe Activity fornece uma quantidade de callbacks que permite rastrear essas atividades.

Dentro dos métodos de callback do ciclo de vida, você pode declarar como a atividade deve se comportar quando o usuário sai e retorna dela.

Image

Por exemplo, se estiver construindo um reprodutor de vídeos de transmissão em sequência, você pode pausar o vídeo e encerrar a conexão da rede quando o usuário alternar para outro aplicativo. Quando o usuário retornar, será possível reconectar a rede e permitir que ele reinicie o vídeo de onde parou. Ou seja, cada callback permite que você realize o trabalho específico adequado a determinada mudança de estado.

Fazer o trabalho certo no momento apropriado e gerenciar as transições da maneira correta faz com que seu aplicativo seja mais robusto e tenha melhor desempenho.

Por exemplo, uma boa implementação dos callbacks de ciclo de vida pode ajudar a garantir que seu aplicativo evite os problemas a seguir:

  • Falhas se o usuário receber uma chamada telefônica ou mudar para outro aplicativo enquanto estiver usando seu aplicativo.
  • Consumo de recursos importantes do sistema quando o usuário não estiver usando ativamente o aplicativo.
  • Perda do progresso do usuário se ele sair do aplicativo e retornar mais tarde. *Falhas ou perda do progresso do usuário quando a orientação da tela mudar entre paisagem e retrato.

A ideia é entender o que acontece internamente quando operam e o que você deve implementar durante a execução deles.

Fonte(s): Google Android Developers

Clean Architecture com MVVM em aplicações Android

A Clean Architecture foi idealizada por Robert C. Martin, autor de um livro abordando este tema, ajudou a criar uma arquitetura em que os componentes fossem desacoplados, testáveis e de fácil manutenção.

O que é a Clean Architecture? A Clean Architecture consiste em um diagrama de camadas, em que cada um dos seus componentes possuem suas próprias responsabilidades e cada uma delas tem conhecimento apenas de camadas de dentro, ou seja, a camada de “Frameworks e Drivers” enxerga somente a de “Interface Adapters”.

Image

Vantagens: O código é facilmente testável, se comparado a arquitetura MVVM simples; Componentes ainda mais desacoplados, a estrutura do pacote é facilmente de se navegar entre eles; Novas funcionalidades podem ser adicionadas rapidamente pelo time de desenvolvedores.

Desvantagens: Curva de aprendizado relativamente íngreme, considerando que todas as camadas funcionam juntas, exigindo um certo tempo para entender seus conceitos, principalmente desenvolvedores provenientes de padrões como MVVM e MVP simples; Pela arquitetura exigir o acréscimo de muitas classes adicionais, este modelo não é ideal para projetos de baixa complexidade. A intenção é de demonstrar as regras de dependência dentro da arquitetura.

Image

Cada camada de MVVM usando Clean Architecture no Android e os códigos se dividem em três camadas:

Camada de Apresentação (Presentation Layer):

Nesta camada, são incluídas as “Activity”s, “Fragment”s como sendo as “Views”, e as “ViewModel”s, devem ser mais simples e intuitivo possível e ainda, não devem ser incluídas regras de negócio nas “Activity”s e “Fragment”s.

Uma “View” irá se comunicar com sua respectiva “ViewModel”, e assim, a “ViewModel” se comunicará com a camada de domínio para que sejam executadas determinadas ações. Uma “ViewModel” nunca se comunicará diretamente com a camada de dados;

Camada de Domínio (Domain Layer):

Na camada de domínio, devem conter todos os casos de uso da aplicação. Os casos de uso tem como objetivo serem mediadores entre suas “ViewModel”s e os “Repository”s.

Caso for necessário adicionar uma nova funcionalidade, tudo o que deve ser feito é adicionar um novo caso de uso e todo seu respectivo código estará completamente separado e desacoplado dos outros casos de uso. A criação de um novo caso de uso é justamente para evitar que ao adicionar novas funcionalidades, quebrar as preexistentes no código;

Camada de Dados (Data Layer):

Esta camada possui todos os repositórios que a camada de domínio tem disponíveis para utilização e “DataSource”s, que são responsáveis por decidir qual a fonte em que devem ser recuperados os dados, sendo de uma base de dados local ou servidor remoto.

Arquitetura Android mvc x mvp x mvvm

Fixando o conhecimento basico em arquiteura Android, vou descrever os Patterns de arquitetura já utilizados:

  • MVC - Model View Controller
  • MVP - Model View Presenter
  • MVVM - Model View ViewModel

MVC

Image

Esta abordagem separa sua aplicação em um nível macro com 3 conjuntos de responsabilidades. Sendo eles:

Model No Model irá conter Data + State + Business Logic, de forma não técnica. Podemos usar como exemplo lógica comercial, acesso a dados e regra de negócios, que não está ligado a View ou Controller e com isto se torna muito reutilizável.

View Representa o Model, ela é a UI (user interface) e faz a comunicação com a Controller sempre que ocorre uma interação do usuário. Quanto menos eles souberem do que deve ser feito com a interação, mais flexíveis serão para mudar.

Controller Ele é o responsável pelo que acontece no aplicativo. Quando a View diz para o Controller que um usuário clicou em um botão, ele decide como interagir. Se ocorrer modificação de dados no Model, o Controller pode decidir atualizar o estado de exibição, quase sempre representado por uma activity ou fragment.

Desvantagens:

Testabilidade - O controlador está tão ligado às APIs do Android que é difícil testar a unidade. Modularidade e flexibilidade - Os Controllers estão bem acoplados às Views. Pode também ser uma extensão da View. Caso você mude a View, devemos voltar e mudar o Controller. Manutenção - Pode ocorrer de o código começar a ser transferido para os Controllers, tornando-os cheios, complexos e com grande facilidade de crashs.

MVP

Image

O MVP quebra o Controller de modo que o acoplamento de View/Activity pode ocorrer sem amarrá-lo ao restante das responsabilidades do “Controller”. Veremos mais sobre isso abaixo, mas comecemos novamente com uma definição comum de responsabilidades, em comparação com o MVC.

Model Igual ao MVC / Nenhuma mudança

View A única alteração aqui é que a Activity/Fragment agora é considerada parte da View. A boa prática é ter uma Activity implementando uma interface de exibição para que o Presenter tenha uma interface para codificar. Com isto é eliminado o acoplamento e permite testes unitários.

Presenter Este é o Controller do MVC, exceto por ele não estar vinculado ao View, apenas a uma interface, com isto ele não mais gerencia o tráfego de solicitações recebidas, como é feito no Controller.

Desvantagens:

Manutenção - Os Presenters, assim como os Controllers, são propensos a colecionar lógica comercial adicional, espalhados com o tempo. Podemos nos deparar com grandes Presenters difíceis de separar.

MVVM

Image

MVVM com o Data Binding tem como benefícios testes mais fáceis e modularidade, ao mesmo tempo que reduz a quantidade de código que temos que escrever para conectar o Model com a View. Este Pattern suporta ligação bidirecional entre View e ViewModel, com isto nos permite ter propagação automática de mudanças. Bem, vou explicar.

Model Igual ao MVC e MVP / Nenhuma mudança

View A View liga-se a variáveis ​Observable ​​e ações expostas pelo ViewModel de forma flexível.

ViewModel O ViewModel é responsável por expor métodos, comandos e propriedades que mantém o estado da View, assim como manipular a Model com resultados de ações da View e preparar dados Observable necessários para a exibição.

Desvantagens:

Manutenção - As Views podem se ligar (bind) a ambas as variáveis ​​e expressões, adicionando código efetivamente ao XML. O ideal é obter valores diretamente do ViewModel em vez de tentar calcular utilizando no XML.