Save 37% off PRO during our Black Friday Sale! »

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.

7a454a0e47136cf3f9a1048537e283db?s=128

Fatih Giriş

October 21, 2021
Tweet

Transcript

  1. Using Kotlin Flow in MVVM S. Fatih Giris Android Lead

    @ DNB Bank fgiris fatih_grs
  2. Sample https://github.com/fgiris/LiveDataWithFlowSample

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

    Only Flow • Testing
  4. LiveData in MVVM • LiveData ✓Lifecycle aware ✓No memory leak

    ✓Cache ✓…
  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
  6. LiveData in MVVM • LiveData - Backpressure ❌ - Data

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

    transformation ❌ - Requires lifecycle owner to observe (Activity, Fragment …) 🤔
  8. LiveData in MVVM • Weather forecast app • One-shot request

    • Data stream
  9. LiveData in MVVM • ViewModel: LiveData • Repository: Suspend Ref:

    https://developer.android.com/jetpack/guide
  10. LiveData in MVVM WeatherForecastRepository.kt

  11. LiveData in MVVM WeatherForecastRepository.kt

  12. LiveData in MVVM WeatherForecastViewModel.kt

  13. LiveData in MVVM WeatherForecastViewModel.kt

  14. LiveData in MVVM WeatherForecastViewModel.kt

  15. LiveData in MVVM WeatherForecastViewModel.kt

  16. LiveData in MVVM WeatherForecastViewModel.kt

  17. Return multiple values?

  18. None
  19. LiveData in MVVM Open Twitter app

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

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

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

    cache Fetch new tweets from server Update UI
  23. LiveData in MVVM WeatherForecastRepository.kt

  24. LiveData in MVVM WeatherForecastRepository.kt

  25. Flow 🤩

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

  27. Flow Pros • Structured concurrency • Cold stream • Efficient

    data transformation • Easy testing
  28. LiveData + Flow • ViewModel: LiveData • Repository: Flow Ref:

    https://developer.android.com/jetpack/guide
  29. LiveData + Flow WeatherForecastRepository.kt

  30. LiveData + Flow WeatherForecastRepository.kt

  31. LiveData + Flow WeatherForecastOneShotViewModel.kt

  32. LiveData + Flow WeatherForecastOneShotViewModel.kt Flow

  33. LiveData + Flow WeatherForecastOneShotViewModel.kt Flow

  34. LiveData + Flow WeatherForecastOneShotFragment.kt

  35. LiveData + Flow WeatherForecastRepository.kt

  36. LiveData + Flow WeatherForecastRepository.kt Data per second

  37. LiveData + Flow WeatherForecastDataStreamViewModel.kt

  38. None
  39. Flow Intermediate Flow Operators • map • filter • transform

    • onEach • …
  40. LiveData + Flow map operator

  41. LiveData + Flow map operator

  42. LiveData + Flow map operator

  43. LiveData + Flow onStart operator

  44. LiveData + Flow filter operator

  45. LiveData + Flow onEach operator

  46. LiveData + Flow flowOn operator

  47. LiveData + Flow catch operator

  48. LiveData + Flow asLiveData extension

  49. Why not only Flow?

  50. LiveData 👋

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

    🙄
  52. Flow WeatherForecastDataStreamFlowViewModel.kt 😭

  53. Flow WeatherForecastDataStreamFlowViewModel.kt No asLiveData

  54. Flow WeatherForecastDataStreamFlowFragment.kt

  55. Flow WeatherForecastDataStreamFlowFragment.kt Terminal Operator 👈

  56. Flow WeatherForecastDataStreamFlowFragment.kt

  57. None
  58. Testing🚦

  59. Testing • LiveData • LiveData & Coroutines might result some

    race condition • Need to observe again when Transformations used
  60. Testing • Flow • Sequential • No race condition •

    Test like a list (toList )
  61. Testing WeatherForecastRepository.kt

  62. Testing WeatherForecastRepositoryTest.kt

  63. Testing WeatherForecastRepositoryTest.kt

  64. Testing WeatherForecastRepositoryTest.kt

  65. Testing WeatherForecastRepositoryTest.kt

  66. Testing WeatherForecastRepositoryTest.kt

  67. Testing WeatherForecastRepositoryTest.kt

  68. Testing WeatherForecastRepositoryTest.kt

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

  70. Testing Solution: TestCoroutineDispatcher

  71. Testing MainCoroutineRule.kt

  72. Testing MainCoroutineRule.kt

  73. Testing MainCoroutineRule.kt

  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 😎
  75. https://medium.com/@girisfth Missed something?

  76. QUESTIONS @fatih_grs

  77. Stay safe!

  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
  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