Escolar Documentos
Profissional Documentos
Cultura Documentos
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 {
fun eat() {
Log.d("Log Eat", "Eating a lot!")
}
}
Classe Abstrata
● Um objeto Adapter atua como uma ponte entre um AdapterView e os dados para essa
exibição.
● 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
https://www.codementor.io/@dragneelfps/implementing-mvc-pattern-in-android-with-kotlin-i9hi2r06c
Arquitetura MVC
https://proandroiddev.com/kotlin-clean-architecture-1ad42fcd97fa
Clean Architecture
Domain: executa uma lógica de regra de negócio independente
de qualquer camada.
Application Flow
Clean Architecture
Direção das Dependências entre as camadas
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
● 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
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
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
● 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);
@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):
build.gradle:
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
Não vem integrado por padrão, tem que adicionar a dependencia no gradle a parte.
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?
● 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.
Podem haver múltiplos Observers registrados para receber dados emitidos por um
Observable.
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:
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.
● 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.
Problemas:
Dagger é uma biblioteca popular de injeção de dependência para Java, Kotlin e Android
mantida pelo Google.
● @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.
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
É uma técnica usada na programação para lidar com as dependências das classes.
● 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 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
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.
● 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.
Esse callback precisa ser implementado. Ele é acionado assim que o sistema cria a
atividade. Quando a activity é criada, ela insere o estado Criado.
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.
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:
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()
Iniciar outra atividade, seja dentro do próprio app ou em outro app, não precisa ser uma
operação de mão única.
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
● Product(Produto abstrato) — define uma interface para os objectos criados pelo factory
method;
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