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

Using Kotlin Flow in MVVM

Using Kotlin Flow in MVVM

LiveData was never designed to be a full-fledged reactive stream. Thread management with LiveData is very hard and making data transformation with transformation operators is very limited. Moreover, testing LiveData becomes very tricky and is likely to open for race conditions if you are using it with coroutines.

Luckily, Kotlin Flow provides asynchronously computed values with the power of Coroutines. Making data transformations becomes very easy with Flow intermediate operators. Furthermore, StateFlow provides caching the current state just like LiveData. Since there is a back-pressure in Flow, unit testing is much simpler with handy Flow terminal operators.

Kotlin Flow is a very powerful reactive stream with its robust operators. Using Flow instead of LiveData makes it easier to handle data transformations and background processes. Finally, testing Flow is much safer and painless compared to LiveData.

Fatih Giriş

October 21, 2021
Tweet

More Decks by Fatih Giriş

Other Decks in Programming

Transcript

  1. Using Kotlin Flow in MVVM
    S. Fatih Giris
    Android Lead @ DNB Bank
    fgiris fatih_grs

    View Slide

  2. Sample
    https://github.com/fgiris/LiveDataWithFlowSample

    View Slide

  3. Agenda
    • LiveData in MVVM
    • LiveData + Flow
    • Only Flow
    • Testing

    View Slide

  4. LiveData in MVVM
    • LiveData
    ✓Lifecycle aware
    ✓No memory leak
    ✓Cache
    ✓…

    View Slide

  5. LiveData in MVVM
    • LiveData
    - Backpressure ❌
    Producer
    Observer
    Ref: https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/4.%20Backpressure.md

    View Slide

  6. LiveData in MVVM
    • LiveData
    - Backpressure ❌
    - Data transformation 🥵

    View Slide

  7. LiveData in MVVM
    • LiveData
    - Backpressure ❌
    - Data transformation ❌
    - Requires lifecycle owner to observe (Activity, Fragment …) 🤔

    View Slide

  8. LiveData in MVVM
    • Weather forecast app
    • One-shot request
    • Data stream

    View Slide

  9. LiveData in MVVM
    • ViewModel: LiveData
    • Repository: Suspend
    Ref: https://developer.android.com/jetpack/guide

    View Slide

  10. LiveData in MVVM
    WeatherForecastRepository.kt

    View Slide

  11. LiveData in MVVM
    WeatherForecastRepository.kt

    View Slide

  12. LiveData in MVVM
    WeatherForecastViewModel.kt

    View Slide

  13. LiveData in MVVM
    WeatherForecastViewModel.kt

    View Slide

  14. LiveData in MVVM
    WeatherForecastViewModel.kt

    View Slide

  15. LiveData in MVVM
    WeatherForecastViewModel.kt

    View Slide

  16. LiveData in MVVM
    WeatherForecastViewModel.kt

    View Slide

  17. Return multiple
    values?

    View Slide

  18. View Slide

  19. LiveData in MVVM
    Open Twitter app

    View Slide

  20. LiveData in MVVM
    Open Twitter app
    Get the tweets from
    cache

    View Slide

  21. LiveData in MVVM
    Open Twitter app
    Get the tweets from
    cache
    Fetch new tweets from
    server
    Update UI

    View Slide

  22. LiveData in MVVM
    Open Twitter app
    Get the tweets from
    cache
    Fetch new tweets from
    server
    Update UI

    View Slide

  23. LiveData in MVVM
    WeatherForecastRepository.kt

    View Slide

  24. LiveData in MVVM
    WeatherForecastRepository.kt

    View Slide

  25. Flow 🤩

    View Slide

  26. Flow
    • Reactive stream which can return asynchronously
    computed values

    View Slide

  27. Flow
    Pros
    • Structured concurrency
    • Cold stream
    • Efficient data transformation
    • Easy testing

    View Slide

  28. LiveData + Flow
    • ViewModel: LiveData
    • Repository: Flow
    Ref: https://developer.android.com/jetpack/guide

    View Slide

  29. LiveData + Flow
    WeatherForecastRepository.kt

    View Slide

  30. LiveData + Flow
    WeatherForecastRepository.kt

    View Slide

  31. LiveData + Flow
    WeatherForecastOneShotViewModel.kt

    View Slide

  32. LiveData + Flow
    WeatherForecastOneShotViewModel.kt
    Flow

    View Slide

  33. LiveData + Flow
    WeatherForecastOneShotViewModel.kt
    Flow

    View Slide

  34. LiveData + Flow
    WeatherForecastOneShotFragment.kt

    View Slide

  35. LiveData + Flow
    WeatherForecastRepository.kt

    View Slide

  36. LiveData + Flow
    WeatherForecastRepository.kt
    Data per second

    View Slide

  37. LiveData + Flow
    WeatherForecastDataStreamViewModel.kt

    View Slide

  38. View Slide

  39. Flow
    Intermediate Flow Operators
    • map
    • filter
    • transform
    • onEach
    • …

    View Slide

  40. LiveData + Flow
    map operator

    View Slide

  41. LiveData + Flow
    map operator

    View Slide

  42. LiveData + Flow
    map operator

    View Slide

  43. LiveData + Flow
    onStart operator

    View Slide

  44. LiveData + Flow
    filter operator

    View Slide

  45. LiveData + Flow
    onEach operator

    View Slide

  46. LiveData + Flow
    flowOn operator

    View Slide

  47. LiveData + Flow
    catch operator

    View Slide

  48. LiveData + Flow
    asLiveData extension

    View Slide

  49. Why not only Flow?

    View Slide

  50. LiveData 👋

    View Slide

  51. Flow
    • Cold stream
    • ≠ LiveData
    • Configuration changes 🙄

    View Slide

  52. Flow
    WeatherForecastDataStreamFlowViewModel.kt
    😭

    View Slide

  53. Flow
    WeatherForecastDataStreamFlowViewModel.kt
    No asLiveData

    View Slide

  54. Flow
    WeatherForecastDataStreamFlowFragment.kt

    View Slide

  55. Flow
    WeatherForecastDataStreamFlowFragment.kt
    Terminal Operator
    👈

    View Slide

  56. Flow
    WeatherForecastDataStreamFlowFragment.kt

    View Slide

  57. View Slide

  58. Testing🚦

    View Slide

  59. Testing
    • LiveData
    • LiveData & Coroutines might result some race condition
    • Need to observe again when Transformations used

    View Slide

  60. Testing
    • Flow
    • Sequential
    • No race condition
    • Test like a list (toList )

    View Slide

  61. Testing
    WeatherForecastRepository.kt

    View Slide

  62. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  63. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  64. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  65. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  66. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  67. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  68. Testing
    WeatherForecastRepositoryTest.kt

    View Slide

  69. Testing
    Dispatchers.Main -> Android Main Looper -> Android OS

    View Slide

  70. Testing
    Solution: TestCoroutineDispatcher

    View Slide

  71. Testing
    MainCoroutineRule.kt

    View Slide

  72. Testing
    MainCoroutineRule.kt

    View Slide

  73. Testing
    MainCoroutineRule.kt

    View Slide

  74. TL;DR
    • Flow & LiveData similar
    • One shot request
    • Repository: Suspend or Flow
    • ViewModel: LiveData or Flow (with repeatOnLifecycle in the View layer)
    • Data stream
    • Repository: Flow
    • ViewModel: LiveData or Flow (with repeatOnLifecycle in the View layer)
    • LiveData Tests 😥 - Flow Tests 😎

    View Slide

  75. https://medium.com/@girisfth
    Missed something?

    View Slide

  76. QUESTIONS
    @fatih_grs

    View Slide

  77. Stay safe!

    View Slide

  78. References
    • https://proandroiddev.com/using-livedata-flow-in-mvvm-part-i-
    a98fe06077a0

    • https://proandroiddev.com/using-livedata-flow-in-mvvm-part-
    ii-252ec15cc93a

    • https://github.com/fgiris/LiveDataWithFlowSample

    • https://developer.android.com/topic/libraries/architecture/livedata

    • https://proandroiddev.com/when-not-to-use-livedata-6a1245b054a6

    • https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/
    kotlinx.coroutines.flow/index.html

    View Slide

  79. References
    • https://medium.com/@elizarov/kotlin-flows-and-
    coroutines-256260fb3bdb

    • https://github.com/Kotlin/kotlinx.coroutines/pull/1354

    • https://codelabs.developers.google.com/codelabs/
    advanced-kotlin-coroutines/

    • https://medium.com/androiddevelopers/unit-testing-livedata-
    and-other-common-observability-problems-bb477262eb04

    • https://medium.com/swlh/kotlin-coroutines-in-android-unit-
    test-28ff280fc0d5

    View Slide