fun onStart() { // Some action at start } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onStop() { // Some action at stop } } // At your Activity / Fragment lifecycle.addObserver(YourLifecycleObserver())
presenters into/from their passive Views Auto register/unregister into/from some external framework, outside Activity/Fragment code Auto track some screen view at every screen resume ETC
Android component (Activity, Fragment) and the "business logic" of the application, with a proper lifecycle scoped according the related component itself"
{ return repository.retrieveFromNetwork() } } object YourViewModelFactory : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here return YourViewModel(repository) as T } }
{ return repository.retrieveFromNetwork() } } object YourViewModelFactory : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here return YourViewModel(repository) as T } }
{ return repository.retrieveFromNetwork() } } object YourViewModelFactory : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here return YourViewModel(repository) as T } }
provided according the scope of the related component A ViewModel scope will stand longer than the related Android component itself (if needed) : a ViewModel survives configuration changes, backed by a retained Fragment
passive view Should store and provide data related to user interface state Plays well with a single source of truth for data retrieving / processing (eg Repository Pattern) onCleared( ) can be used to release colaborators Should not have any Android framework related code
return object : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here! return YourViewModel(repository) as T } } } }
return object : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here! return YourViewModel(repository) as T } } } }
return object : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>?): T { val repository = // Retrieve your repository here! return YourViewModel(repository) as T } } } }
or RESUMED lifecycle states Ensures that a destroyed observer will not get any updates It not holds any data history, only the actual data state We can perform a few functional operations over LiveData via the Transformations API
MutableLiveData<T> Allows some client object to modify the contents of data - setValue( ) to update from the Android main thread - postValue( ) to update from another thread MediatorLiveData<T> An abstraction to combine two or more LiveDatas in a desired way
Only publishes results on Android MainThread Offers a "bridge" to RxJava2 reactive types, but it should be avoided (personal opinion) Confusing roles for MutableLiveData and LiveData (personal opinion)
USER App on a new state Swipe-off from recents USER App on a new state Explicit finish( ) USER (call to action) App on a new state Configuration changes (rotation, locale, etc) DEVICE / USER App on the same state as before Resources reclaim, application in background ANDROID SYSTEM App on the same state as before Process death in extreme conditions, app in background ANDROID SYSTEM App on the same state as before
the actual screen state, but each one of them has pros and cons to be dealt with. A comprehensive strategy may use all three ways together : the answer will be given by the application context"
CHANGES ? IS DATA READY FOR THE SCREEN ? AMOUNT OF DATA AVAILABLE RESISTS SYSTEM CRASHING / REBOOT DEMANDS IO ACCESS? Bundle YES YES PROBABLY YES SMALL (order of KB) NO NO ViewModel NO (Process Death) YES PROBABLY YES LARGE (order of MB) NO NO Local Storage YES YES PROBABLY NO LARGER (order of GB) YES YES
information footprint that you need to rebuild the entire screen state from the other available means, usually information generated by user interactions (inputed texts, actual page from a large list, actual list position, etc) ViewModel Store related-and-processed data for screen, acessed previously from a single source of truth (Networking, Database, etc) behind a repository Local Storage Store data as soon you get it. Data format may not be UI-related at all, and can be adapted for the UI at ViewModel or Repository level
overabuse ViewModels Use an Observer Pattern implementation to communicate between ViewModels and Activity / Fragments ( ) ViewModels should be a very tiny layer : leverage some presentation strategy to avoid fat classes!