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

Android + Kotlin Coroutines: Async de um jeito ...

Android + Kotlin Coroutines: Async de um jeito "diferente"

Slides do um talk realizado no Android Meetup SP, que aconteceu em São Paulo, no dia 6 de Março de 2018.

O talk foi sobre o que são e como utilizar Kotlin Coroutines no Android de um jeito simples e prático.

Link: https://www.meetup.com/pt-BR/GDG-SP/events/248170951/

Walmyr Carvalho

March 06, 2018
Tweet

More Decks by Walmyr Carvalho

Other Decks in Technology

Transcript

  1. E hoje temos uma biblioteca “vencedora” no que diz respeito

    a operações assíncronas no Android em geral.
  2. Coroutines no Kotlin são threads "mais leves”, com uma sintaxe

    de código assíncrono tão direta quanto a de um código síncrono.
  3. Elas são tipos de funções chamadas suspending functions, e tem

    seus métodos marcados com a palavra chave suspend.
  4. // roda o código em uma thread pool em background

    fun asyncOverlay() = async(CommonPool) { // inicia duas operações assíncronas val original = asyncLoadImage("original") val overlay = asyncLoadImage("overlay") // e aplica o overlay para os dois resultados applyOverlay(original.await(), overlay.await()) } // executa a coroutine no contexto de UI launch(UI) { val image = asyncOverlay().await() showImage(image) }
  5. O launch é a maneira mais simples de se criar

    uma coroutine numa thread em background, tendo um Job (uma task em background, basicamente) como sua referência para si.
  6. public actual fun launch( context: CoroutineContext = DefaultDispatcher, start: CoroutineStart

    = CoroutineStart.DEFAULT, parent: Job? = null, block: suspend CoroutineScope.() -> Unit ): Job
  7. Conceitualmente, o async é similar ao launch, mas a diferença

    deles é que o async retorna um Deferred, que é basicamente uma future (ou promise).
  8. public actual fun <T> async( context: CoroutineContext = DefaultDispatcher, start:

    CoroutineStart = CoroutineStart.DEFAULT, parent: Job? = null, block: suspend CoroutineScope.() -> T ): Deferred<T>
  9. Tecnicamente, um Deferred é um Job, só que com uma

    future com uma promessa de entregar um valor em breve.
  10. Ou seja: No async você tem a mesma funcionalidade do

    launch, mas com a diferença que ele retorna um valor no .await():
  11. fun getUser(userId: String): User = async { // return User

    } launch(UI) { val user = getUser(id).await() navigateToUserDetail(user) }
  12. Também é possível rodar alguma operação bloqueando completamente a thread,

    utilizando o runBlocking, mas não é algo muito necessário no Android:
  13. Resumindo: Se não faço questão de um callback -> launch

    Se eu preciso esperar uma future (Deferred) -> async Se eu preciso bloquear minha thread -> runBlocking
  14. val job = launch { // do your stuff }

    job.cancel() val job = launch { while (isActive){ //do your stuff } }
  15. fun main(args: Array<String>) = runBlocking { try { val user:

    User = api.getUser("username").await() println("User ${user.name} loaded") } catch (e: HttpException) { println("exception${e.code()}", e) } catch (e: Throwable) { println("Something broken", e) } }