Você está na página 1de 122

Aula Android

18 de julho de 2020
● Classe Abstrata

● Adapter

Arquitetura MVC
Conteúdo ●

● Clean Architecture

● RxJava
Classe Abstrata

REGRAS:

● Uma classe abstrata descreve os métodos, mas não necessariamente implementa todos os métodos.

● Uma classe abstrata não pode ser instanciada. Significa que não pode existir um objeto do tipo classe
abstrata. Para usar essa classe, você cria uma outra classe que estende a classe abstrata e
implementa os métodos abstratos. Aí você pode usar o objeto dessa classe filha para chamar os
métodos da classe abstrata.

● Se uma classe filha não implementa todos os métodos abstratos da classe abstrata, então essa classe
filha precisa ser abstrata também.
Classe Abstrata

Uma classe abstrata descreve os métodos, mas não necessariamente implementa todos os métodos.
abstract class Person {

abstract fun cook(needsHelp: Boolean) : Boolean

abstract fun walk()

fun eat() {
Log.d("Log Eat", "Eating a lot!")
}

}
Classe Abstrata

Uma classe abstrata não pode ser


instanciada.
Classe Abstrata

Se uma classe filha não implementa todos os


métodos abstratos da classe abstrata, então
essa classe filha precisa ser abstrata
também.
Adapter

● Um objeto Adapter atua como uma ponte entre um AdapterView e os dados para essa
exibição.

● O Adapter provê acesso aos dados dos itens.

● O Adapter também é responsável por criar uma visualização para cada item no conjunto
de dados.
Adapter
Adapter (RecyclerView) onCreateViewHolder onBindViewHolder getItemCount
ViewHolder
Adapter
com
Múltiplas
Views
Arquitetura MVC

MVC (Model-View-Controller) é um padrão de projeto de software que separa a


interface do usuário (View) e das regras de negócio e dados (Model) usando um
mediador (Controller) para conectar o modelo à view.
Arquitetura MVC

O principal benefício do MVC é a separação de interesses. Cada parte do MVC


cuida de seu próprio trabalho: a view cuida da interface com o usuário, o modelo se
encarrega dos dados, e o controlador envia mensagens entre os dois.
Arquitetura MVC

https://www.codementor.io/@dragneelfps/implementing-mvc-pattern-in-android-with-kotlin-i9hi2r06c
Arquitetura MVC

Dev Media - Android MVC: Criando um Framework Model-View-Controller para


Android
https://www.devmedia.com.br/android-mvc-criando-um-framework-model-view-controller-para-android/29924

* Medium - Android MVC x MVP x MVVM qual Pattern utilizar — Parte 1


https://medium.com/@FilipeFNunes/android-mvc-x-mvp-x-mvvm-qual-pattern-utilizar-parte-1-3defc5c89afd
Clean Architecture
Clean Architecture

● Separação de código em diferentes camadas com responsabilidades


atribuídas, facilitando novas modificações.

● Alto nível de abstração

● Acoplamento fraco entre o código

● Teste de código é sem complicações

https://proandroiddev.com/kotlin-clean-architecture-1ad42fcd97fa
Clean Architecture
Domain: executa uma lógica de regra de negócio independente
de qualquer camada.

Data: provê dados requisitados pelo aplicativo implementando


a interface exposta pelo domínio.

Presentation: inclui as camadas Domain e Data e é


especificamente o Android que executa a lógica da interface
do usuário.
Domain Layer
Data Layer
Presentation Layer
Clean Architecture

Application Flow
Clean Architecture
Direção das Dependências entre as camadas
Testes

Em resumo seu app


deve conter:

● 70% testes small


ou unitários
● 20% testes medium
ou integrados
● 10% testes large ou
end-to-end
Testes

● Testes Unitários
○ Ficam no pacote .../test/…
○ Não fazem uso do emulador/smartphone
○ Recursos do framework Android não vão ser acessíveis por padrão (com dependências
direta/indireta com a classe Context)
○ Podem ser executados apenas com JUnit e ferramentas de Mock
○ Execução de testes mais rápida
Testes Unitários
Testes Unitários

Para construir testes de


maneira efetiva é
importante que o app
tenha arquitetura bem
estruturada e utilizar
princípios de injeção de
dependência.
Testes - Robolectric

É um framework de testes que permite que recursos específicos do Android


sejam simulados sem a necessidade de carregar um emulador ou dispositivo
real. (Sendo assim conseguimos testar classes que dependam do Context ou
outras classes do Android de maneira rápida e fácil dentro do pacote de testes
não instrumentados.
Testes - Robolectric
Testes - Instrumentados

● Testes Instrumentados
○ Ficam no pacote .../androidTest/…
○ Rodam em aparelhos físicos ou em emuladores
○ Reduz o uso de Mocks e usa a implementação real do framework do Android
○ Execução dos testes fica mais lenta
○ Nível maior de confiabilidade e integração

● Pode ser dividido em três categorias:


○ Testes integrados exclusivamente com AndroidJUnitRunner + AndroidJUnit4
○ Testes de UI com Espresso
○ Testes end-to-end com UI Automator
Testes - AndroidJUnitRunner + AndroidJUnit4

AndroidJUnitRunner é um test runner que permite com que testes do JUnit sejam
executados sobre aparelhos Android. Serve como base para todos os testes
instrumentados.
Testes - Exemplo de Teste Instrumentado

Testes que envolvam


persistência de
dados ou que
acessem recursos
reais do Android
(como strings.xml),
podem ser feitos na
camada
instrumentada da
pirâmide.
Testes com Espresso
O Espresso é uma ferramenta de automação de testes de UI feitas para pessoas desenvolvedoras que
possuem mais familiaridade com a codebase.

A maneira de escrever um teste de Espresso é diferente de como escrevemos testes com Robolectric
ou testes instrumentados com JUnit. Nele nós temos uma forma de escrever que se assemelha muito
com o que um usuário faria na sua App.
Testes
Teste end-to-end com UI Automator

O objetivo aqui é testar se um fluxo está se comportando corretamente do início ao fim.

A principal diferença entre o Espresso e o UI Automator é que o Espresso testa a UI em um escopo


muito mais isolado e o UI Automator consegue testar em um escopo muito mais abrangente que vai
além da aplicação que está sendo construída (por exemplo escrever um teste que acesse as
configurações do device).

Uma outra vantagem do UI Automator é a possibilidade escrever um testes end-to-end utilizando o


mesmo projeto no Android Studio.
Teste end-to-end com UI Automator
Ferramentas de Suporte:

● UI Automator Viewer: Que é uma ferramenta feita para inspecionar o layout da sua tela com
mais detalhes e ajudar a extrair informações como IDs e content descriptions. Essa ferramenta
esta localizada no caminho <android-sdk>/tools

● Classe UiDevice: Classe no código que fornece funções auxiliares como mudar a orientação do
device, apertar o botão back ou home e até abrir o menu de notificações.
Teste end-to-end com UI Automator
Teste end-to-end com UI Automator
Ressalva: os testes com UI Automator são os mais pesados e mais sensíveis a mudanças de
sistema. Qualquer atualização do Google Play Services ou do próprio sistema operacional podem
impactar seu testes. Aviso na documentação oficial:
ViewModelProvider.Factory

É uma interface responsável por instanciar ViewModels. Por default ela instancia o
construtor primário (sem argumentos).
Retrofit

É uma bibliotecas de HTTP Client para Android e Java, produzida pela Square Inc. e
lançada como open source para toda comunidade.
Retrofit
Consumir rotas determinadas:

@GET("shots")
Call<List<ShotsVO>>getShotsList(@Query("access_token") String accessToken);

Retrofit retrofit = new Retrofit.Builder()


.baseUrl("https://api.dribbble.com/v1/")
.build();

WebServiceApi webServiceApi = retrofit.create(WebServiceApi.class);


//Resultado final: https://api.dribbble.com/v1/shots
Retrofit
Acessar uma URL diferente:

@GET("http://api.icndb.com/jokes/random")
Call<JokeVO> getAJoke();
//Inserindo URL diretamente pelo campo da anotação de HTTP verb

ou

@GET
Call<JokeVO> getAJoke(@Url String url);
//Inserindo anotação @Url dentro do método
Retrofit
Adicionar Interceptors (header, log):

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();


httpClient.addInterceptor(new Interceptor(){
@Override
public Response intercept(Chain chain) throws IOException{
...
}
}

Retrofit retrofit = new Retrofit.Builder()


.baseUrl(Environment.SERVER_URL)
.client(httpClient.build())
.build();
Retrofit
Adicionar Log Interceptor:

build.gradle:
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'

HttpLogginInterceptor interceptor = new HttpLogginInterceptor();


interceptor.setLevel(Environment.LOG_LEVEL);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(interceptor);
Retrofit
Converters

Não vem integrado por padrão, tem que adicionar a dependencia no gradle a parte.

Retrofit retrofit = new Retrofit.Builder()


.baseUrl(Environment.SERVER_URL)
.addConverterFactory(LoganSquareConverterFactory.create())
.build();
Retrofit
Requests Síncrono:

Basta usar: “call.execute”

Exemplo:
Call<List<ShotsVO>> call = apiInstance.getListShots();
List<ShotsVO> shotsList = call.execute.body;
Retrofit
Requests Assíncrono:

Usar: “call.enqueue(…)”

Exemplo:
Call<List<ShotsVO>> call = apiInstance.getShotsList();
call.enqueue(new CallBack<List<ShotsVO>>(){
@Override
public void onResponse(Call<List<ShotsVO>> call, Response<List<ShotsVO>> response){

}
override fun onFailure(call: Call<List<ShotsVO>>, t: Throwable) {
...
}
})
Retrofit
Cancelar requests:

Usar: “call.cancel()”

Exemplo:
Call<List<ShotsVO>> call = apiInstance.getShotsList();
call.enqueue(new CallBack<List<ShotsVO>>(){
@Override
public void onFailure(Call<List<ShotsVO>> call, Throwable throwable){
if(call.isCanceled()){
//requisição foi cancelada
}
else{
//provavelmente houve um erro de conexão
}
}
}
RxJava
É uma biblioteca que permite representar de forma declarativa, qualquer operação
como um fluxo assíncrono de dados, que pode ser criado por qualquer thread, e
consumido por múltiplos objetos em (opcionalmente) threads diferentes.

Onde usar?

● Acesso à rede, tais como chamadas HTTP;


● Leitura e escrita no sistema de arquivos e banco de dados;
● Controle de eventos de UI que devem disparar ações;
● Tratamento de dados dos sensores do aparelho;
● Envio de mensagens internas da aplicação;
● etc...
RxJava - Uso Comum
É muito utilizado como forma mais elegante para resolver problemas que podem
ser solucionados com algumas bibliotecas de terceiros e/ou APIs nativas do
Android:

● AsyncTask (Observable + Observer)


● Chaining callbacks (callbacks encadeados)
● Handler / TimerTask
● Retrofit. Call pattern? (Adapter-RxJava)
● EventBus (PublishSubject)
RxJava - Elementos fundamentais
O RX Java tem os seguintes elementos principais:

● Observables
● Observers
● Schedulers
● Operators
RxJava
Observable: tipo de emissor que emite um fluxo de dados de forma sequencial (por
padrão). Esse fluxo normalmente é consumido por um Observer.

É similar ao Iterable do Java (acesso síncrono ao fluxo de dados).

Observers: são os objetos que consomem os dados emitidos por um Observable.

Podem haver múltiplos Observers registrados para receber dados emitidos por um
Observable.

Observers tratam quaisquer erros que ocorram (onError) enquanto o Observable


está emitindo (onNext) dados. Ele também saberá quando não houver mais itens a
serem consumidos (onComplete).
RxJava
Criar um Observable que emite apenas um item

Com o just foi criado um objeto Observable que emite apenas a String "Hello RX". No
subscribe é registrado um observer/consumer/receiver dos dados que serão emitidos.
O valor emitido é recebido como parâmetro (instrução lambda).
RxJava
Criar um Observable
que emite mais de um
item

* Existem outras
variações do from*
para criar um
Observable.
RxJava - Outros Tipos de Emissores

Além do Observable,
existem outros tipos
de emissores:
RxJava - Outros Métodos no Observable

doOnSubscribe,
doOnNext, doOnError,
doOnComplete, …
Schedulers
Determinam a thread em que o emissor emitirá seu fluxo de dados e a thread em
que os Observers consumirão essas informações. Os principais são:

● Main Thread (AndrdoiSchedulers.mainThread()


● Computation (Schedulers.computation())
● I/O ( Schedulers.io())
● Nova thread (Schedulers.newThread())
Transformers
Operadores
Os operadores manipulam os itens entre o produtor (Observable) e o consumidor
(Observer). O RX Java tem uma infinidade de operadores.

map:
Operadores

filter:

take:
Operadores
zip:
Disposable
Ao realizar uma subscription em um Observable, uma instância de Disposable é
retornada. Isso permite liberar os recursos e threads alocadas para o Observer por meio
do método dispose.
PublishSubject

A classe
PublishSubject é uma
subclasse de Subject
e funciona como
Observable e
Observer ao mesmo
tempo. Pois além
receber dados (como
um Observer) ele
também emite (como
um Observable).
ConnectableObservable
Por padrão, cada vez que um Observer se registra em um Observable, a sequência é enviada novamente. É
possível fazer com que a mesma emissão seja enviada para Observables diferentes utilizando a classe
ConnectableObservable.
O método publish() retorna um
ConnectableObservable para os Observers
podem se registrar. Foi utilizado o
autoConnect(2) para determinar que as
emissões podem começar após dois
observables se registrarem. Outra forma seria
utilizar o método connect() para que o envio
seja realizado para todos os Observers.
Injeção de Dependência

É uma técnica usada na programação para lidar com as dependências das classes.

A implementação da injeção de dependência oferece as seguintes vantagens:

● Reutilização do código
● Facilidade de refatoração
● Facilidade de teste
Injeção de Dependência
As classes geralmente exigem referências a outras classes.

Este não é um exemplo de injeção de dependência porque a classe Car


está criando o próprio Engine.

● Car e Engine estão fortemente acoplados.

● A forte dependência de Engine dificulta os testes. Car usa uma


instância real de Engine.
Injeção de Dependência
Qual é a aparência do código com a injeção de dependência? Em vez de cada instância
de Car criar o próprio objeto Engine na inicialização, ele recebe um objeto Engine

Este não é um exemplo de injeção de dependência porque a classe Car


está criando o próprio Engine.

● Reutilização de Car. É possível transmitir implementações


diferentes de Engine para Car.

● Teste fácil de Car.


Injeção de Dependência Manual
Há duas maneiras principais de fazer a injeção de dependência no Android:
Injeção de construtor. Injeção de campo (ou injeção de setter)
Injeção de Dependência Manual

Problemas:

● Para apps grandes, conseguir todas as dependências e conectá-las


corretamente pode exigir uma grande quantidade de código de texto clichê.

● Quando não for possível criar dependências antes de transmiti-las, por


exemplo, no caso de inicializações lentas ou objetos de escopo para fluxos do
app.
Injeção de Dependência Automática

Existem bibliotecas que resolvem esse problema automatizando o processo de


criação e disponibilizando dependências. Elas se encaixam em duas categorias:

● Soluções baseadas em reflexões que conectam dependências no tempo de


execução.

● Soluções estáticas que geram o código para conectar dependências no tempo


de compilação.
Injeção de Dependência - Dagger

Dagger é uma biblioteca popular de injeção de dependência para Java, Kotlin e Android
mantida pelo Google.

Fornece dependências totalmente estáticas e no tempo de compilação.

A Dagger facilita o uso de DI no seu app, criando e gerenciando o gráfico de


dependências para você.
Injeção de Dependência - Dagger Annotations
Temos:

● @Inject: Anotação utilizada quando se necessita pedir alguma dependência.

● @Module: Anotação utilizada em classes que fornecem dependências.

● @Provides: Anotação utilizadas em métodos que proveem dependências, os


métodos provedores são encontrados nas classes com a anotação @Module.

● @Component: São basicamente injetores, uma ponte entre módulos e provides, neles
definimos quem pode utilizar nossos módulos e quais módulos são utilizados.
Injeção de Dependência - Module

Cria um Module
e Provides
Injeção de Dependência
Como utilizar os
provides?

Usando a
annotation
@Inject
Injeção de Dependência
Ao utilizar o @Inject, estamos pedindo para que seja fornecido um objeto de Exemplo. O Dagger2
verifica qual o objeto solicitado e busca em seus provides.

Ao prover uma instância de Exemplo, o Dagger 2


checa que esta possui uma dependência de
Usuario e busca essa dependência em seus
provedores:
Injeção de Dependência - Component
Injeção de Dependência - Component

Devemos disponibilizar nosso


ComponenteExemplo em um local
que seja acessível a todos.
Normalmente é criada uma
referência junto com nossa classe
Application do projeto.

A classe DaggerComponentExemplo é
gerada em tempo de compilação.
(precisa fazer o build do projeto)
Injeção de Dependência
Informar sobre o uso do Module

Agora precisamos informar ao Dagger 2 que nossa classe fará uso de um dos nossos Components:
Injeção de Dependência - Koin

Ferramenta de injeção de dependência desenvolvida em Kotlin como alternativa ao


Dagger!

Dagger é bem poderoso e comum no ambiente Android. Porém, a compreensão e


configuração exige um bom tempo do desenvolvedor, fazendo com que muitos até
mesmo evitem o seu uso.
Injeção de Dependência

É uma técnica usada na programação para lidar com as dependências das classes.

A implementação da injeção de dependência oferece as seguintes vantagens:

● Reutilização do código
● Facilidade de refatoração
● Facilidade de teste
Injeção de Dependência - Koin

A base de configuração do Koin é por meio de seus módulos, que são as entidades
que mantém as instruções de como as dependências devem ser inicializadas.

Para configurar, utiliza-se a função module(), que é uma Higher-Order Function.


Injeção de Dependência - Módulo
Criando a instância de um Adapter.

Para definir a instância, é adicionada a função Para enviar o Context foi utilizada a função
factory, que indica ao Koin que cada vez que get() que é uma função que resolve
injetar uma instância com a referência dependências das instâncias definidas.
ProductListAdapter, ele vai criar uma instância
nova.
Injeção de Dependência - Koin
Inicializando o Koin:

É necessário inicializar
o Koin a partir da
função startKoin()
dentro de uma entidade
que tenha referência ao
Context do Android.
Essa inicialização pode
ser feita no onCreate()
da Activity.
Injeção de Dependência

Injetando dependencias

Após o Koin inicializado, as dependencias são injetadas usando a keyword inject()


Injeção de Dependência
Definindo instâncias de objetos com mais complexidade
Injeção de Dependência
Definindo instâncias de objetos com mais complexidade

Criando a injeção da DAO, que tem como dependência o AppDatabase.

Primeiro pedimos ao Koin para que ele


nos forneça uma instância do
AppDatabase e que a partir dela,
queremos que ele crie pra gente a
instância do DAO.
Injeção de Dependência
Detalhes sobre a inicialização do Koin

Para que o Koin funcione da maneira esperada, a sua inicialização precisa ser feita apenas uma única vez em
um local mais seguro do que uma Activity, pois se a Activity for destruída e criada novamente (algo bem
comum de acontecer), perdemos as referências pelas quais ele fez a injeção.

Um local comum de mantermos essa


configuração é dentro da entidade mais
estável de um App enquanto está
rodando, a Application.
Injeção de Dependência - Koin
Organização dos Módulos

● Banco de dados;
● Interface do usuário.
Ciclo de Vida Activity

A classe Activity fornece uma quantidade de callbacks que permite que a atividade
saiba sobre a mudança do estado: informa a respeito da criação, interrupção ou
retomada de uma atividade ou da destruição do processo em que ela reside por
parte do sistema.
Ciclo de Vida Activity
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.
Ciclo de Vida Activity

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().
Ciclo de Vida Activity - onCreate()

Esse callback precisa ser implementado. Ele é acionado assim que o sistema cria a
atividade. Quando a activity é criada, ela insere o estado Criado.

● Chama a superclass para completar a criação da activity.


● Recupera estado da instancia (savedInstanceState)
● Define o layout xml para a activity (setContentView)
● Inicializa elementos do layout (findViewById)
Ciclo de Vida Activity - onStart()

Quando a activity insere o estado "Iniciado", o sistema invoca esse callback. A chamada
onStart() torna a activity 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.

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().
Ciclo de Vida Activity - onResume()

Quando a activity 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 activity
ou desativar a tela do dispositivo.
Ciclo de Vida Activity - onResume()

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.
Ciclo de Vida Activity - onPause()

O sistema chama esse método


como a primeira indicação de que o
usuário está deixando sua activity,
embora nem sempre signifique que
a activity esteja sendo destruída.
Isso indica que a activity não está
mais em primeiro plano, embora
ainda possa estar visível se o
usuário estiver no modo de várias
janelas.
Ciclo de Vida Activity - onPause()

O que foi alocado no onResume(),


deve ser liberado no onPause().

A execução onPause() é muito breve e


não oferece necessariamente tempo
suficiente para realizar operações de
salvamento. Por isso, não use
onPause() para salvar dados do
aplicativo ou do usuário, fazer
chamadas de rede ou executar
transações do banco de dados. Esse
tipo de trabalho pode não ser concluído
antes da finalização do método.
Ciclo de Vida Activity - onStop()
Quando a activity 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 activity
recém-iniciada preenche toda a tela. O sistema também poderá chamar onStop() quando
a activity parar de operar e estiver prestes a ser concluída.

Se você não encontrar um momento mais oportuno para salvar informações em um


banco de dados, poderá fazer isso durante onStop().
Ciclo de Vida Activity - onStop()

A partir do estado
"Interrompido", a activity
volta a interagir com o
usuário ou para de operar e
é encerrada. Se a activity
voltar, o sistema invocará
onRestart(). Caso a Activity
deixe de operar, o sistema
chamará onDestroy().
Ciclo de Vida Activity - onDestroy()
onDestroy() é chamado antes de a activity ser destruída. O sistema invoca esse callback
porque:

● a activity está sendo finalizada (pelo fato do usuário descartá-la completamente ou


devido a finish() ser chamado na activity);

● o sistema está destruindo temporariamente a activity devido a uma mudança na


configuração (como a rotação do dispositivo ou o modo de várias janelas)

É possível distinguir entre essas duas situações com o método isFinishing().


Ciclo de Vida Activity - onDestroy()
Em vez de inserir lógica à sua activity para determinar por que ela está sendo destruída,
use um objeto ViewModel para manter os dados de visualização relevantes a ela.

Se a activity for recriada devido a uma mudança na configuração, o ViewModel não


precisará realizar nenhuma ação. Ela será preservada e fornecida à próxima instância da
activity.

Se a activity não for recriada, o ViewModel chamará o método onCleared(), em que ele
pode limpar os dados necessários antes da destruição.
Ciclo de Vida Activity - onDestroy()

Caso a activity esteja sendo encerrada,


onDestroy() será o callback do ciclo de
vida final recebido pela activity.

Se onDestroy() for chamado como o


resultado da mudança na configuração, o
sistema criará imediatamente uma nova
instância de activity e chamará onCreate()
nessa instância na nova configuração.
onActivityResult

Usado para ver o resultado de uma atividade.

Iniciar outra atividade, seja dentro do próprio app ou em outro app, não precisa ser uma
operação de mão única.

Você também pode iniciar outra atividade e receber um resultado.

Por exemplo, o app pode iniciar um app de câmera e receber a foto capturada como
resultado. Ou você pode iniciar o app Contatos para que o usuário selecione um contato
e receber os detalhes do contato como resultado.
onActivityResult
onActivityResult
Factory Method

Factory Method ou Construtor virtual, é um design pattern que permite às classes


delegar para subclasses decidirem através da criação de objetos que chamam o método
fábrica especificado numa interface e implementado por um classe filha ou
implementado numa classe abstrata e opcionalmente sobrescrito por classes derivadas.
Factory Method - Consequências

Positivas: Baixo acoplamento, maior flexibilidade e elimina a necessidade de acoplar


classes específicas para aplicação em nível de código.

Negativas: Alto número de classes, podendo sobrecarregar o sistema.


Factory Method - Estrutura

O padrão Factory Method contém os seguintes elementos:

● Creator(Criador abstrato) — declara o factory method (método de fabricação) que retorna o


objeto da classe Product (produto). Este elemento também pode definir uma implementação
básica que retorna um objeto de uma classe ConcreteProduct (produto concreto) básica;

● ConcreteCreator(Criador concreto) — sobrescreve o factory method e retorna um objeto da


classe ConcreteProduct;

● Product(Produto abstrato) — define uma interface para os objectos criados pelo factory
method;

● ConcreteProduct(Produto concreto) — uma implementação para a interface Product.


Factory Method - Exemplo

Classes abstratas:
Aplicacao e Documento

Classes concretas:
MinhaAplicacao e MeuDocumento

MinhaAplicacao implementa a
abstracao definida em Aplicacao
Factory Method

Resumo:

O Factory Method permite que você crie objetos sem especificar a classe exata do
objeto que vai ser criado.
Factory Method
Super class
Factory Method
Sub class
Factory Method
Sub class
Factory Method - Factory class
Factory Method - Utilização
Factory Method - Vantagens

● Fornece abordagem ao código para interface em vez de implementação.

● Remove a instanciação das classes de implementação reais do código do cliente. O


padrão de fábrica torna nosso código mais robusto, menos acoplado e fácil de
estender.

● Fornece abstração entre a implementação e as classes do cliente por meio de


herança.
Factory Method - Exemplo Refrigerante

Você também pode gostar