MVVM, Viewmodel and architecture components

MVVM, Viewmodel and architecture components

UAmobile, Kiev

A8b79d304b5184e5a5b0a109590f6683?s=128

Danny Preussler

November 25, 2017
Tweet

Transcript

  1. 2.
  2. 7.

    In architecture components •A ViewModel provides the data for a

    specific UI •The ViewModel does not know about the View! •Survives configuration change
  3. 8.

    In architecture components •A ViewModel provides the data for a

    specific UI •The ViewModel does not know about the View! •Survives configuration change
  4. 9.

    In architecture components •A ViewModel provides the data for a

    specific UI •The ViewModel does not know about the View! •Survives configuration change
  5. 10.

    In architecture components •A ViewModel provides the data for a

    specific UI •The ViewModel does not know about the View! •Survives configuration change
  6. 17.

    How to use override fun onCreate(...) { model = ViewModelProviders

    .of(this) .get(MyViewModel::class.java) }
  7. 19.

    How to use class MyViewModelFactory :ViewModelProvider.Factory(useCase: MyUseCase) { fun <T:

    ViewModel> create(aClass: Class<T>): T { return MyViewModel(useCase) as T } }
  8. 21.

    How to use •Always try to build your own Factory

    •Default factory uses newInstance() which is some hundred times slower than new calls (reflection) https://speakerdeck.com/dpreussler/comparing-dependency-injection- frameworks-and-internals-for-android
  9. 22.

    How to use •Always try to build your own Factory

    •Default factory uses newInstance() which is some hundred times slower than new calls (reflection) https://speakerdeck.com/dpreussler/comparing-dependency-injection- frameworks-and-internals-for-android
  10. 23.
  11. 25.
  12. 27.

    How does it actually work? class HolderFragment extends Fragment {

    public HolderFragment() { setRetainInstance(true); } …
  13. 30.

    How does it actually work? @Override public void onDestroy() {

    super.onDestroy(); mViewModelStore.clear(); }
  14. 35.

    What if Two Fragments of same Activity ask for same

    ViewModel.class via ViewModelProviders .of(this) .get(MyViewModel::class.java)
  15. 37.

    What if Two Fragments of same Activity ask for same

    ViewModel.class via ViewModelProviders .of(this) .get(MyViewModel::class.java)
  16. 38.
  17. 39.

    result •Fragment and Activity share the same FragmentManager •But implementation

    uses Activity’s FragmentManager but ChildFragmentManager for Fragments
  18. 40.

    result •Fragment and Activity share the same FragmentManager •But implementation

    uses Activity’s FragmentManager but ChildFragmentManager for Fragments
  19. 41.

    What if Two Fragments of same Activity ask for same

    ViewModel.class via ViewModelProviders .of(getActivity()) .get(MyViewMode::class).java
  20. 52.

    Is MVP dead? It’s like Java and Kotlin: •MVP will

    stay for quite some time •There is a new cooler kid in town that won’t leave
  21. 53.

    Is MVP dead? It’s like Java and Kotlin: •MVP will

    stay for quite some time •There is a new cooler kid in town that won’t leave
  22. 54.

    Is MVP dead? It’s like Java and Kotlin: •MVP will

    stay for quite some time •There is a new cooler kid in town that won’t leave
  23. 58.

    IntroduciNG LIVE DATA •Observable similar to RxJava •Life cycle aware

    •Doesn’t emit when not needed •Memory leaks save
  24. 65.

    ViewModel in data binding <TextView … android:id="@+id/all_shows_item_title" android:text="@{viewModel.title}" /> <data>

    <variable name="viewModel" type="com.vmn.playplex.main.allshows.AllShowsViewModel"/> </data>
  25. 66.

    ViewModel in data binding <android.support.v7.widget.CardView … android:onClick="@{() -> viewModel.onClicked()}"> <data>

    <variable name="viewModel" type="com.vmn.playplex.main.allshows.AllShowsViewModel"/> </data>
  26. 68.

    How to use class AllShowsViewModel: ViewModelObservable() { @Bindable var title

    : CharSequence = "" private set(value) { if (field != value) { field = value notifyPropertyChanged(BR.title) } }
  27. 69.

    How to use class AllShowsViewModel: ViewModelObservable() { @Bindable var title

    by bindable<CharSequence>("") private set Custom property delegate
  28. 70.

    How to use class AllShowsFragment : Fragment () { @Inject

    lateinit var showsViewModel: AllShowsViewModel
  29. 71.

    How to use class AllShowsFragment : Fragment () { @Inject

    lateinit var showsViewModel: AllShowsViewModel override fun onCreateView(…):View? =
  30. 72.

    How to use class AllShowsFragment : Fragment () { @Inject

    lateinit var showsViewModel: AllShowsViewModel override fun onCreateView(…):View? = FragmentShowsBinding.inflate( inflater, container, false).apply { viewModel = showsViewModel }).root
  31. 73.

    How to use class AllShowsFragment : Fragment () { @Inject

    lateinit var showsViewModel: AllShowsViewModel override fun onCreateView(…):View? = FragmentShowsBinding.inflate( inflater, container, false).apply { viewModel = showsViewModel }).root fragment_shows.xml
  32. 74.

    How to use class MyViewModel() :ViewModelObservable() { Coming soon Jose

    Alcérreca, Google https://medium.com/@dpreussler/add-the-new-viewmodel-to-your-mvvm-36bfea86b159
  33. 76.

    .. show a toast class SeriesViewModel : Viewmodel() { …

    @Bindable var error = ObservableField<String>()
  34. 80.

    WAYS TO OBSERVE DATA from VM? •Data binding Observable from

    xml or code, might need unregister •RxJava Observable from code, needs unregister •LiveData Observable, from code, no unregister, life cycle aware
  35. 81.

    let`s sum up •Architecture components are here •Use the parts

    you need •Goal: common architecture language •Databinding rocks •Know about life cycle
  36. 82.

    Want to know more • https://medium.com/@dpreussler/add-the-new- viewmodel-to-your-mvvm-36bfea86b159 • https://proandroiddev.com/customizing-the-new- viewmodel-cf28b8a7c5fc

    • http://hannesdorfmann.com/android/arch-components- purist • https://blog.stylingandroid.com/architecture-components- viewmodel/ • https://www.youtube.com/watch?v=QrbhPcbZv0I • https://www.youtube.com/watch?v=c9-057jC1ZA
  37. 87.

    all problems solved? ViewModels provide a convenient way to retain

    data across configuration changes but they are not persisted if the application is killed by the operating system https://developer.android.com/topic/libraries/architecture/viewmodel.html#viewm odel_vs_savedinstancestate
  38. 89.

    Why? The data saved via onSaveInstanceState is kept in the

    system process memory and the Android OS allows you to keep only a very small amount of data so it is not a good place to keep actual data for your app. TransactionTooLargeException anyone?
  39. 91.

    after The truth •Keep non-UI states in non-UI layer Not

    in bundle! •Use real caching strategies •Allows updating cache in background
  40. 92.

    after The truth •Keep non-UI states in non-UI layer Not

    in bundle! •Use real caching strategies •Allows updating cache in background
  41. 93.

    after The truth •Keep non-UI states in non-UI layer Not

    in bundle! •Use real caching strategies •Allows updating cache in background
  42. 94.
  43. 100.

    lets tweak it class MyModelFactory(val bundle: Bundle?) :ViewModelProvider.Factory() { …

    fun <T: ViewModel> create(aClass: Class<T>): T { return MyViewModel().apply { readFrom(bundle) } as T } ...