Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

Activable

Equips View Models with a very simple lifecycle.

Note: you don't need this library if you use Decompose. A Decompose component has its own lifecycle.

Why does View Model need a lifecycle?

Despite that View Model should be abstracted away from the corresponding View (Activity or Fragment) it still needs to be aware of Android lifecycle. It is the common case when View Model subscribes to a Repository in order to update UI whenever something is changed in a database. But it is wasteful to keep a database subcription when a screen is placed to a backstack or the whole application is in background. It is better to subscribe and unsubscribe according to a lifecycle.

How complex should a lifecycle be?

Activity and Fragment lifecycles are quite complex. There are onCreate, onStart, onResume, onPause, onStop and onDestroy callbacks. Sesame activable component is build on assumption that View Model doesn't need such a complex lifecycle.
First of all it doesn't need onCreate and onDestroy. Any initialization can be done in init-block instead of onCreate. onDestroy is intended to clean up something. In View Models we typically cancel started coroutines and unsubscribe from flows in the clean-up. All of these are made automatically with help of viewModelScope.
onResume-onPause and onStart-onStop are different callback pairs in Android. But View Model can be abstract enough to ignore the difference. In other words View Model is only interested if a screen is active. The such simple lifecycle has just two methods: onActive and onInactive.

Make View Model activable

  1. Implement Activable interface in a base View Model class. Kotlin delegation is handy here.
abstract class BaseViewModel : ViewModel(), Activable by Activable() {

}
  1. Bind activable View Model to Activity/Fragment lifecycle with bindToLifecycle method. It translates onStart to onActive and onStop to onInactive.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    vm.bindToLifecycle(viewLifecycleOwner.lifecycle)
}
  1. Use the lifecycle callbacks in a child class.
class MyViewModel: BaseViewModel() {

    override fun onActive() {
        super.onActive()
        // Do something
    }

    override fun onInactive() {
        // Do something
        super.onInactive()
    }
}

Activable flow

In the section Why View Model needs a lifecycle? the common task is described: View Model subscribes to updates from a Repository, subscription should be established only when View Model is active. Sesame helps to solve this task.

Given a flow of updates:

val profileFlow: Flow<Profile> = profileRepository.observeProfile()

Use activableFlow(originalFlow, activable, coroutineScope) to convert it to an activable flow.

val activableProfileFlow = activableFlow(profileFlow, this, viewModelScope)

An activable flow collects the original flow and emits elements further when the activable is active. It stops collecting and emitting when the activable is inactive.