Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Utilizando Kotlin Coroutines no seu app Android

Utilizando Kotlin Coroutines no seu app Android

Coroutines são uma ótima forma de escrever código assíncrono de um jeito muito simples e fácil, tanto para ler quanto manter. Nesta palestra irei abordar os conceitos básicos de Coroutines e Suspend Functions explicando sua abordagem por meio de exemplos de código, e a sua aplicação dentro do contexto Android. O objetivo será compartilhar de forma geral o conceito, e o entendimento do motivo dessa ferramenta do Kotlin estar ganhando tanto espaço no mundo de desenvolvimento atual.

Angélica Oliveira

September 24, 2019
Tweet

More Decks by Angélica Oliveira

Other Decks in Programming

Transcript

  1. Sobre o que vamos falar? - Coroutines - Coroutine Builders

    - Suspending Functions - Dispatchers - Coroutines Scope - Testes com Coroutines 3
  2. Coroutines 5 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos
  3. Coroutines 6 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc
  4. Coroutines 7 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc - Se bloquearmos a Main Thread por muito tempo, o app pode apresentar o erro Application Not Responding
  5. Coroutines 8 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc - Se bloquearmos a Main Thread por muito tempo, o app pode apresentar o erro Application Not Responding - O conceito de Coroutines já existe há bastante tempo, e existe em várias linguagens, não surgiu com o Kotlin
  6. Coroutines 9 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc - Se bloquearmos a Main Thread por muito tempo, o app pode apresentar o erro Application Not Responding - O conceito de Coroutines já existe há bastante tempo, e existe em várias linguagens, não surgiu com o Kotlin - Possibilita a execução de rotinas assíncronas de uma forma simples de se implementar e manter
  7. Coroutines 10 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc - Se bloquearmos a Main Thread por muito tempo, o app pode apresentar o erro Application Not Responding - O conceito de Coroutines já existe há bastante tempo, e existe em várias linguagens, não surgiu com o Kotlin - Possibilita a execução de rotinas assíncronas de uma forma simples de se implementar e manter - As chamadas assíncronas são escritas da mesma forma que um código sequencial, eliminando a necessidade de termos callbacks
  8. Coroutines 11 - No Android, para uma aplicação ser exibida

    sem pausas, a Main Thread precisa atualizar a tela a cada 16ms ou menos - Temos muitas tarefas que podem levar mais tempo que isso, como JSON parsing, uso de banco de dados, etc - Se bloquearmos a Main Thread por muito tempo, o app pode apresentar o erro Application Not Responding - O conceito de Coroutines já existe há bastante tempo, e existe em várias linguagens, não surgiu com o Kotlin - Possibilita a execução de rotinas assíncronas de uma forma simples de se implementar e manter - As chamadas assíncronas são escritas da mesma forma que um código sequencial, eliminando a necessidade de termos callbacks - Uma coroutine pode ter a sua execução suspensa em determinado ponto, e retomada em um momento posterior, continuando a partir do mesmo ponto em que parou
  9. Coroutines Builders 13 - runBlocking - A thread fica bloqueada,

    só retomando a sua execução depois do término da execução da coroutine
  10. Coroutines Builders runBlocking 14 fun main() { println("Hello,") // block

    the main thread runBlocking { // now we are inside a coroutine delay(2000L) // suspends for 2 seconds } // will be executed after 2 seconds println("Coroutines!") }
  11. Coroutines Builders 15 - runBlocking - A thread fica bloqueada,

    só retomando a sua execução depois do término da execução da coroutine - launch - Inicia uma coroutine sem bloquear a thread atual, que continua a sua execução normalmente
  12. Coroutines Builders launch 16 fun main() { GlobalScope.launch { //

    launch new coroutine in background and continue delay(1000L) println("Coroutines!") } println("Hello,") // main thread continues here immediately runBlocking { delay(2000L) // ... 2 seconds to keep JVM alive } }
  13. Coroutines Builders 17 - runBlocking - A thread fica bloqueada,

    só retomando a sua execução depois do término da execução da coroutine - launch - Inicia uma coroutine sem bloquear a thread atual, que continua a sua execução normalmente - async - Também inicia uma coroutine sem bloquear a thread atual, utilizada para retornar um valor ao término de sua execução
  14. Coroutines Builders async 18 fun main() { val deferredResult: Deferred<String>

    = GlobalScope.async { // suspend for 1 second delay(1000L) // this is the result "Coroutine!" } runBlocking { println("Hello") // wait for the result println(deferredResult.await()) } }
  15. Suspending Functions Sunspending Functions no Contexto Android 23 onDraw onDraw

    onDraw requestLogin UI Thread show onDraw onDraw onDraw onDraw
  16. Suspending functions são funções regulares do Kotlin que possuem o

    modificador suspend para identificar que elas chamam um código que pode suspender a execução de uma coroutine. 24
  17. - Coroutines sempre executam em um determinado contexto definido pelo

    tipo CoroutineContext - O contexto da Coroutine é um conjunto de vários elementos, os principais são: - Job - Dispatcher 26 Coroutines Context
  18. - Jobs são executáveis que possuem um ciclo de vida

    - Podem possuir uma hierarquia parent-child - Os estados de um Job são definidos pelas flags: - isActive - isCompleted - isCancelled 27 Coroutines Context Job
  19. - Responsável por determinar que Thread ou Threads a Coroutine

    usa para sua execução - Todos os builders de Coroutine aceitam especificar o Dispatcher e outros elementos do contexto ao iniciar uma coroutine 29 Dispatchers
  20. 30 Dispatchers Dispatchers.Main - Main thread - Utilizado em: UI

    operations Dispatchers.Default - Pool de threads compartilhadas - Utilizado em: coroutines com tarefas de computação intensa (algoritmos pesados, cálculos) Dispatchers.IO - Pool de threads compartilhadas criadas conforme a necessidade - Utilizado em: operações de entrada/saída (comunicação com servidor) Dispatchers.Unconfined - Não confina a coroutine em uma determinada thread - Evitar a sua utilização durante a implementação
  21. 31 Dispatchers Dispatchers.Main - Main thread - Utilizado em: UI

    operations Dispatchers.Default - Pool de threads compartilhadas - Utilizado em: coroutines com tarefas de computação intensa (algoritmos pesados, cálculos) Dispatchers.IO - Pool de threads compartilhadas criadas conforme a necessidade - Utilizado em: operações de entrada/saída (comunicação com servidor) Dispatchers.Unconfined - Não confina a coroutine em uma determinada thread - Evitar a sua utilização durante a implementação
  22. 32 Dispatchers Dispatchers.Main - Main thread - Utilizado em: UI

    operations Dispatchers.Default - Pool de threads compartilhadas - Utilizado em: coroutines com tarefas de computação intensa (algoritmos pesados, cálculos) Dispatchers.IO - Pool de threads compartilhadas criadas conforme a necessidade - Utilizado em: operações de entrada/saída (comunicação com servidor) Dispatchers.Unconfined - Não confina a coroutine em uma determinada thread - Evitar a sua utilização durante a implementação
  23. 33 Dispatchers Dispatchers.Main - Main thread - Utilizado em: UI

    operations Dispatchers.Default - Pool de threads compartilhadas - Utilizado em: coroutines com tarefas de computação intensa (algoritmos pesados, cálculos) Dispatchers.IO - Pool de threads compartilhadas criadas conforme a necessidade - Utilizado em: operações de entrada/saída (comunicação com servidor) Dispatchers.Unconfined - Não confina a coroutine em uma determinada thread - Evitar a sua utilização durante a implementação
  24. Coroutines Scope 35 - Coroutines Scope facilitam o controle do

    ciclo de vida das coroutines, podemos controlar de acordo com o ciclo de vida da view
  25. Coroutines Scope 36 - Coroutines Scope facilitam o controle do

    ciclo de vida das coroutines, podemos controlar de acordo com o ciclo de vida da view - Podemos controlar manualmente, utilizando os métodos da ViewModel
  26. 37 class MyViewModel: ViewModel() { val viewModelJob = Job() val

    uiScope = CoroutineScope(Dispatchers.Main+viewModelJob) fun login( username: String, pass: String ) = uiScope.launch(Dispatchers.IO) { val result = requestLogin(name, pass) show(result) } fun onCleared() { super.onCleared() viewModelJob.cancel() } }
  27. Coroutines Scope 38 - Coroutines Scope facilitam o controle do

    ciclo de vida das coroutines, podemos controlar de acordo com o ciclo de vida da view - Podemos controlar manualmente, utilizando os métodos da ViewModel - Podemos utilizar o viewModelScope - lifecycle-viewmodel-ktx
  28. 39 class MyViewModel: ViewModel() { fun login( username: String, pass:

    String ) = viewModelScope.launch(Dispatchers.IO) { val result = requestLogin(name, pass) show(result) } }
  29. - Chamada que sobrescreve o Main Dispatcher em situações de

    testes 41 Coroutines Tests Dispatcher.setMain
  30. - Chamada que sobrescreve o Main Dispatcher em situações de

    testes - Pode ser utilizado quando: - Main dispatcher não está disponível 42 Coroutines Tests Dispatcher.setMain
  31. - Chamada que sobrescreve o Main Dispatcher em situações de

    testes - Pode ser utilizado quando: - Main dispatcher não está disponível - É necessário sobrescrever por questões de sincronia dos testes (com uma implementação de um Dispatcher na classe de testes) 43 Coroutines Tests Dispatcher.setMain
  32. // overrides Main Dispatcher with a test implementation Dispatchers.setMain(dispatcherImplementation) //

    reset Main Dispatcher with original implementation Dispatchers.resetMain() 44 Coroutines Tests Dispatcher.setMain
  33. Provê controle extra para testar as coroutines: - Avanço do

    tempo automático para suspend functions - Avanço do tempo manual para testar coroutines múltiplas - Execução pausada de chamadas async e launch - Pausa, avanço ou recomeço das coroutines em um teste - Reportar exceções como falhas de testes 45 Coroutines Tests runBlockingTest
  34. Provê controle extra para testar as coroutines: - Avanço do

    tempo automático para suspend functions - Avanço do tempo manual para testar coroutines múltiplas - Execução pausada de chamadas async e launch - Pausa, avanço ou recomeço das coroutines em um teste - Reportar exceções como falhas de testes 46 Coroutines Tests runBlockingTest
  35. Provê controle extra para testar as coroutines: - Avanço do

    tempo automático para suspend functions - Avanço do tempo manual para testar coroutines múltiplas - Execução pausada de chamadas async e launch - Pausa, avanço ou recomeço das coroutines em um teste - Reportar exceções como falhas de testes 47 Coroutines Tests runBlockingTest
  36. Provê controle extra para testar as coroutines: - Avanço do

    tempo automático para suspend functions - Avanço do tempo manual para testar coroutines múltiplas - Execução pausada de chamadas async e launch - Pausa, avanço ou recomeço das coroutines em um teste - Reportar exceções como falhas de testes 48 Coroutines Tests runBlockingTest
  37. Provê controle extra para testar as coroutines: - Avanço do

    tempo automático para suspend functions - Avanço do tempo manual para testar coroutines múltiplas - Execução pausada de chamadas async e launch - Pausa, avanço ou recomeço das coroutines em um teste - Reportar exceções como falhas de testes 49 Coroutines Tests runBlockingTest
  38. - TestCoroutineScope provê controle detalhado da execução das coroutines nos

    testes 50 Coroutines Tests TestCoroutineScope e TestCoroutineDispatcher
  39. - TestCoroutineScope provê controle detalhado da execução das coroutines nos

    testes - TestCoroutineDispatcher é o dispatcher utilizado quando se executa uma coroutine com TestCoroutineScope 51 Coroutines Tests TestCoroutineScope e TestCoroutineDispatcher
  40. - TestCoroutineScope provê controle detalhado da execução das coroutines nos

    testes - TestCoroutineDispatcher é o dispatcher utilizado quando se executa uma coroutine com TestCoroutineScope - Ambos se integram com runBlockingTest 52 Coroutines Tests TestCoroutineScope e TestCoroutineDispatcher