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

Improving app performance with Kotlin Coroutines

Hassan Abid
November 16, 2019

Improving app performance with Kotlin Coroutines

Coroutines were added to Kotlin in version 1.3 and since then they became a popular choice for android developers to simplify code that executes asynchronously. Coroutines are lightweight threads and on android they help to solve the primary problems of long running tasks that might block the main thread and also providing safety for offloading network or disk operations from the main thread. This talk covers how coroutines work with architecture components

Hassan Abid

November 16, 2019
Tweet

More Decks by Hassan Abid

Other Decks in Programming

Transcript

  1. Improving app performance with Kotlin Coroutines Hassan Abid - GDE

    Android 
 Twitter / Instagram @hassanabidpk
  2. –Android Developers Website A coroutine is a concurrency design pattern

    that you can use on Android to simplify code that executes asynchronously.
  3. Why we need Asynchronous? • Main Thread has to update

    screen every 16ms which is 60Hz (frames per second) fetchImage(url)
  4. // Async callbacks networkRequest { result -> // Successful network

    request databaseSave(result) { rows -> // Result saved } } // The same code with coroutines val result = networkRequest() // Successful network request databaseSave(result) // Result saved
  5. Manage Long running Tasks suspend fun fetchDocs() { // Dispatchers.Main

    val result = get("https://developer.android.com") // Dispatchers.IO for `get` show(result) // Dispatchers.Main } suspend fun get(url: String) = withContext(Dispatchers.IO) { /* ... */ }
  6. Main-safety • Safely call network operations from main thread •

    Safely call disk operations from main thread
  7. CoroutineContext • Every coroutine in Kotlin has a context that

    is represented by an instance of CoroutineContext interface • Optimized : It stays on same dispatcher and avoids switching threads
  8. CoroutineDispatcher • The coroutine context includes a coroutine dispatcher that

    determines what thread or threads the corresponding coroutine uses for its execution. scope.launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher // code }
  9. Dispatchers suspend fun fetchDocs() { // Dispatchers.Main val result =

    get("developer.android.com") // Dispatchers.Main show(result) // Dispatchers.Main } suspend fun get(url: String) = // Dispatchers.Main withContext(Dispatchers.IO) { // Dispatchers.IO (main-safety block) /* perform network IO here */ // Dispatchers.IO (main-safety block) } // Dispatchers.Main }
  10. Dispatchers • Dispatchers.Main : Main Android Thread • Dispatchers.IO :

    For Network and Database (Room) calls • Dispatchers.Default : For CPU-intensive tasks
  11. CoroutineScope • Defines a scope for new coroutines • CoroutinesScope

    stops/cancels coroutines execution when user leaves a content area with your app e.g activity, fragment • It should be implemented on entities with a well defined lifecycle (activity, fragment)
  12. Start a coroutine • launch : Doesn’t return result to

    the caller • async : Returns a result with suspend function await
  13. example : launch returns a Job without result fun onDocsNeeded()

    { val job = viewModelScope.launch { // Dispatchers.Main fetchDocs() // Dispatchers.Main (suspend function call) } job.cancel() }
  14. example : async (Parallel Decomposition) suspend fun fetchTwoDocs() = coroutineScope

    { val deferredOne = async { fetchDoc(1) } val deferredTwo = async { fetchDoc(2) } deferredOne.await() deferredTwo.await() } returns a Deffered
  15. CoroutineScope with Android Arch Components • Associate CoroutineScope implementations with

    a lifecycle component • Helps in avoiding Memory Leak • Hint : ViewModel?
  16. Coroutines with Android Arch components • viewModelScope • use androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-beta01

    or higher. • lifeCycleScope • use androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01 or higher. • liveData • use androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha01 or higher.
  17. Life-cycle aware coroutines scope: viewModelScope class MyViewModel: ViewModel() { init

    { viewModelScope.launch { // Coroutine that will be canceled when the ViewModel is cleared. } } }
  18. Life-cycle aware coroutines scope: lifeCycleScope class MyFragment: Fragment() { override

    fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewLifecycleOwner.lifecycleScope.launch { val params = TextViewCompat.getTextMetricsParams(textView) val precomputedText = withContext(Dispatchers.Default) { PrecomputedTextCompat.create(longTextContent, params) } TextViewCompat.setPrecomputedText(textView, precomputedText) } } }
  19. Special cases class MyFragment: Fragment { init { lifecycleScope.launchWhenStarted {

    try { // Call some suspend functions. } finally { // This line might execute after Lifecycle is DESTROYED. if (lifecycle.state >= STARTED) { // Here, since we've checked, it is safe to run any // Fragment transactions. } } } } }
  20. Life-cycle aware coroutines scope: liveData val user: LiveData<Result> = liveData

    { emit(Result.loading()) try { emit(Result.success(fetchUser())) } catch(ioException: Exception) { emit(Result.error(ioException)) } } fun <T> liveData( context: CoroutineContext = EmptyCoroutineContext,..)
  21. Flow • Flow is a cold stream that give us

    same behaviour as that of Observable and Flowable in RxJava • Android Dev Summit 2019 Talk https:// www.youtube.com/watch?v=B8ppnjGPAGE • Docs : https://kotlinlang.org/docs/reference/coroutines/ flow.html
  22. Coroutines for Reactive Streams kotlinx-coroutines-reactive -- utilities for Reactive Streams

    kotlinx-coroutines-reactor -- utilities for Reactor kotlinx-coroutines-rx2 -- utilities for RxJava 2.x
  23. Summary • Coroutines are great - Start using them •

    If you are already using RxJava, you are FINE. You can slowly migrate to Coroutines.
  24. Resources (Videos) • Android Suspenders (Android Dev Summit 2019) https://

    www.youtube.com/watch?v=EOjq4OIWKqM • Understanding Coroutines on Android (Google IO 19) https://www.youtube.com/watch?v=BOHK_w09pVA
  25. Resources (Docs) • Kotlin Docs : https://kotlinlang.org/docs/reference/ coroutines-overview.html • Android

    + Coroutines Docs : https:// developer.android.com/kotlin/coroutine • Coroutines + Android Arch components : https:// developer.android.com/topic/libraries/architecture/ coroutines