Slide 1

Slide 1 text

Programação Assíncrona com Kotlin Coroutines Wellington Costa Pereira

Slide 2

Slide 2 text

Wellington Costa Pereira ● +4 anos de experiência ● Mestrando em Ciências da Computação ● Android Leader na Resource IT Solutions ● Open source <3 ● Compartilhar conhecimento <3 GitHub: https://github.com/WellingtonCosta E-mail: [email protected]

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Exemplo fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 5

Slide 5 text

Estilo Tradicional fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 6

Slide 6 text

Estilo Tradicional fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 7

Slide 7 text

Estilo Tradicional fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 8

Slide 8 text

Callbacks to the rescue

Slide 9

Slide 9 text

Callback fun updateUserData(username: String) { fetchUserFromApi(username) { user -> fetchReposFromApi(username) { repos -> saveUserDataInDb(user, repos) } } }

Slide 10

Slide 10 text

Callback fun updateUserData(username: String) { fetchUserFromApi(username) { user -> fetchReposFromApi(username) { repos -> saveUserDataInDb(user, repos) } } }

Slide 11

Slide 11 text

Coroutines to the rescue

Slide 12

Slide 12 text

Coroutines suspend fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 13

Slide 13 text

Coroutines suspend fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Principais Conceitos

Slide 16

Slide 16 text

Principais Conceitos ● Modificador suspend ● launch vs async ● Dispatchers ● withContext ● coroutineScope ● runBlocking

Slide 17

Slide 17 text

Modificador suspend A suspending function is simply a function that can be paused and resumed at a later time. They can execute a long running operation and wait for it to complete without blocking.

Slide 18

Slide 18 text

Modificador suspend suspend fun updateUserData(username: String) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) }

Slide 19

Slide 19 text

launch vs async launch: A background job. Conceptually, a job is a cancellable thing with a life-cycle that culminates in its completion. It returns a Job instance. async: Deferred value is a non-blocking cancellable future. It’s a Job that has a result. It returns a Deferred instance.

Slide 20

Slide 20 text

launch vs async fun doSomething() { launch { // do some operation } }

Slide 21

Slide 21 text

launch vs async private val jobs = ArrayList() fun doSomething() { jobs.add( launch { // do some operation } ) } override fun onCleared() { jobs.forEach { if(!it.isCancelled) it.cancel() } }

Slide 22

Slide 22 text

launch vs async fun doSomething() { async { // do some operation } }

Slide 23

Slide 23 text

launch vs async fun doSomething() { val deferred = async { // do some operation } val result = deferred.await() }

Slide 24

Slide 24 text

launch vs async fun doSomething() { val result = async { // do some operation }.await() }

Slide 25

Slide 25 text

Dispatchers ● Dispatchers.Main: A coroutine dispatcher that is confined to the Main thread operating with UI objects. ● Dispatchers.Default: A coroutine dispatcher to execute CPU-bound tasks. ● Dispatchers.IO: A coroutine dispatcher that is designed for offloading blocking IO tasks to a shared pool of threads.

Slide 26

Slide 26 text

withContext Calls the suspending block with a given coroutine context, suspends until it completes and then returns the result.

Slide 27

Slide 27 text

withContext suspend fun updateUserData(username: String) { withContext(Dispatchers.IO) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) } }

Slide 28

Slide 28 text

withContext suspend fun updateUserData(username: String) { withContext(Dispatchers.IO) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) } }

Slide 29

Slide 29 text

withContext suspend fun updateUserData(username: String) { withContext(Dispatchers.IO) { val user = fetchUserFromApi(username) val repos = fetchReposFromApi(username) saveUserDataInDb(user, repos) } }

Slide 30

Slide 30 text

coroutineScope This function is designed for a parallel decomposition of work. When any child coroutine in this scope fails, this scope fails and all the rest of the children are cancelled.

Slide 31

Slide 31 text

coroutineScope suspend fun processPayments(): List { coroutineScope { val payments = withContext(Dispatchers.IO) { async { loadPayments() } } val processedPayments = withContext(Dispatchers.Default) { async { calculateInterestRate(payments.await()) } } return processedPayments.await() } }

Slide 32

Slide 32 text

runBlocking Runs new coroutine and blocks current thread until its completion.

Slide 33

Slide 33 text

runBlocking suspend fun processPayments(): List { // load payments and calculate its interest rate } @Test fun myAwesomeTest() { val payments = processPayments() // assert payments interest rate }

Slide 34

Slide 34 text

runBlocking suspend fun processPayments(): List { // load payments and calculate its interest rate } @Test fun myAwesomeTest() = runBlocking { val payments = processPayments() // assert payments interest rate }

Slide 35

Slide 35 text

Perguntas?

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Obrigado!