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

Coroutines on the way!

Coroutines on the way!

This was given on GDG Santiago DevFest 2019

Armando Picón

October 04, 2019
Tweet

More Decks by Armando Picón

Other Decks in Programming

Transcript

  1. Coroutines on the way! Armando Picón Android Engineer at Cornershop

    Inc. @devpicon https://medium.com/@devpicon Using Coroutines in your Android App
  2. Challenge 1: Execute on a non-UI thread Challenge 2: Get

    informed when the task is done Android solutions • AsyncTask • Loaders (deprecated in Android P) • RxJava • Thread / HandlerThread / Executor with callbacks
  3. Threads and callbacks fun login(name, pass) { val thread =

    Thread(Runnable { requestLogin(name, pass) { result -> show(result) } }) thread.start() }
  4. Threads and callbacks fun login(name, pass) { val thread =

    Thread(Runnable { requestLogin(name, pass) { result -> Handler(Looper.getMainLooper()) { show(result) } } }) thread.start()
  5. onDraw onDraw onDraw requestLogin UI Thread fun login(name, pass) {

    requestLogin(name, pass) { result -> show(result) } }
  6. onDraw onDraw onDraw requestLogin UI Thread fun login(name, pass) {

    requestLogin(name, pass) { result -> show(result) } }
  7. onDraw onDraw onDraw requestLogin UI Thread show onDraw fun login(name,

    pass) { requestLogin(name, pass) { result -> show(result) } }
  8. onDraw onDraw onDraw requestLogin UI Thread show onDraw fun login(name,

    pass) { requestLogin(name, pass) { result -> show(result) } } onDraw onDraw onDraw
  9. Coroutine Write asynchronous code sequentially fun login(name, pass) = launch

    { val result = requestLogin(name, pass) show(result) }
  10. Coroutine ~ lightweight thread fun login(name, pass) = launch {

    val result = requestLogin(name, pass) show(result) }
  11. fun login(name, pass) = launch(Dispatchers.IO){ val result = requestLogin(name, pass)

    withContext(Dispatchers.Main) { show(result) } } Coroutine • Not bound to a specific thread • Complete with a result
  12. suspend fun requestLogin( name: String, pass: String ): Result {...}

    Las funciones suspendidas no bloquean el hilo de invocación
  13. Dispatchers.Default • Common pool of shared background threads • Use

    it for: computing-intensive coroutines Dispatchers.Main • Main thread • Use it for: UI operations
  14. Dispatchers.Default • Common pool of shared background threads • Use

    it for: computing-intensive coroutines Dispatchers.IO • Shared pool of on-demand created threads • Use it for: IO-intensive blocking operations Dispatchers.Main • Main thread • Use it for: UI operations
  15. Dispatchers.Default • Common pool of shared background threads • Use

    it for: computing-intensive coroutines Dispatchers.Unconfined • Doesn’t confine the coroutine to any specific thread • Don’t use it in code Dispatchers.IO • Shared pool of on-demand created threads • Use it for: IO-intensive blocking operations Dispatchers.Main • Main thread • Use it for: UI operations
  16. suspend fun login(name, pass) { val result = requestLogin(name, pass)

    show(result) } suspend fun requestLogin( name: String, pass: String ): Result = withContext(Dispatchers.IO) { ... }
  17. suspend fun login(name, pass) { val authToken = authenticate() val

    result = requestLogin(authToken, name, pass) show(result) } Sequential
  18. suspend fun login(name, pass) { val authToken = authenticate() val

    result = requestLogin(authToken, name, pass) show(result) } Data dependencies
  19. suspend fun login(name, pass) { try { val result =

    requestLogin(name, pass) show(result) } catch (error: NetworkError){ } } Errors
  20. Login button pressed Launch coroutine requestLogin Show login status val

    job = Job() val uiScope = CoroutineScope(Dispatchers.Main + job)
  21. Login button pressed Launch coroutine requestLogin Show login status val

    job = Job() val uiScope = CoroutineScope(Dispatchers.Main + job) fun login(username: String, pass: String ) = uiScope.launch { val result = requestLogin(name, pass) show(result) }
  22. Login button pressed Launch coroutine requestLogin Show login status val

    job = Job() val uiScope = CoroutineScope(Dispatchers.Main + job) fun login(username: String, pass: String ) = uiScope.launch(Dispatchers.IO) { val result = requestLogin(name, pass) show(result) }
  23. val job = Job() val uiScope = CoroutineScope(Dispatchers.Main + job)

    fun login( username: String, pass: String ) = uiScope.launch { val result = requestLogin(name, pass) show(result) } job.cancel()
  24. Login button pressed Launch coroutine requestLogin Show login status ViewModel

    fun onCleared() { super.onCleared() job.cancel() }
  25. 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() } }
  26. 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() } } lifecycle-viewmodel-ktx
  27. class MyViewModel: ViewModel() { fun login( username: String, pass: String

    ) = viewModelScope.launch(Dispatchers.IO) { val result = requestLogin(name, pass) show(result) } }
  28. • Coroutines • suspend functions • Dispatchers • Launching a

    coroutine • Using a coroutine from ViewModels
  29. • Coroutines • suspend functions • Dispatchers • Launching a

    coroutine • Using a coroutine from ViewModels • Testing coroutines • Using coroutines with other Jetpack libraries • Channels
  30. • Kotlin Official Documentation https://kotlinlang.org/docs/reference/coroutines-overview.html • Improve app performance with

    Kotlin Coroutines https://developer.android.com/kotlin/coroutines • Coroutines in Kotlin 1.3 explained: Suspending functions, contexts, builders and scopes https://antonioleiva.com/kotlin-coroutines/ • Kotlin Coroutines by Tutorials https://store.raywenderlich.com/products/kotlin-coroutines-by-tutorials
  31. Ahora es tu turno! codelabs.developers.google.com/ codelabs/ kotlin-coroutines Armando Picón Android

    Engineer at Cornershop Inc. @devpicon https://medium.com/@devpicon