
Lifecycle — Aware Components
Architecture components are a set of android libraries that helps your app structure in a way that is testable, reusable, maintainable.
There are few lifecycle aware android architecture components:
- ViewModel: Helps to create, store and retrieve data and communicates with other components belonging to the same lifecycle.
- Lifecycle Owner: It’s an interface implemented by activity and fragment, to observe changes to the lifecycle of owners.
- LiveData: Allows observing changes in data across diff components in the same lifecycle.
View Model
ViewModel is a class that is responsible for preparing and managing data for Activities and Fragments. It also helps in communication between views.
It is the backbone of MVVM architecture. A ViewModel is always created with a scope and will be retained as long as the scope is alive. For example, we bind ViewModel scope with activity then until the activity is running we can change data and get updates of data.
It exposes data using LiveData or DataBinding.
MVVM architecture’s main players are Views, ViewModel, and DataModel. Activity and Fragments are views, they should contain view hierarchy.
Data manipulation, business logic, data fetch from server, database operation should never happen in the view layer. For this work we have ViewModel. It notifies views about diff events.
This is how we define ViewModel in our view class:
UserModel userModel = new ViewModelProvider(this).get(UserModel.class);
this
refers to an instance of lifecycleOwner
. That means ViewModel will be alive until lifecycleOwner is alive. That means when configuration changes happen like screen rotation, ViewModel will remain unaffected.
Let’s see the following diagram for lifecycle:

As you can see from the diagram when the screen is rotated activity and fragment instance is destroyed but ViewModel’s not.
Example :

Now when you rotate the device, it doesn’t save its state, and it losses the editText’s content.
Now do the same using ViewModel.
Now rotate the screen and you will see the data is preserved and there is no glitch in retaining data. So ViewModel helps us to handle configuration changes.
Use ViewModel to handle configuration changes
ViewModel is a good choice for storing and managing UI-related data. It allows quick access to data and helps you avoid prefetching data from the network or database when configuration changes happen like scree rotation and resizing of the app. ViewModel retains data. in memory which means it is. easy to access them.
Unlike saved instance states, ViewModels are destroyed during a system-initiated process death. This is why you should use ViewModel objects in combination with onSaveInstanceState() (or some other disk persistence), stashing identifiers in saved instance state to help view models reload the data after system death.
Use saved instance state as a backup for system-initiated process death.
- Share data between fragments
Commonly, we want to share data between fragments. FOr example normal list of songs and then a detail or play view of that selected song. We can achieve that by view the model using their activity scope.
private val model: SharedViewModel by activityViewModels()
By this approach, both fragments are independent of each other. And independently using a shared ViewModel.
LiveData
LiveData is a data holder class that can be observed within a given lifecycle.
The observer will be notified about the modification of wrapped data inside livedata class.
An observer added with a Lifecycle will be automatically removed if the corresponding Lifecycle moves to Lifecycle.State.DESTROYED
state.
This class is designed to hold individual data fields of ViewModel
, but can also be used for sharing data between different modules in your application in a decoupled fashion.
See more here: https://developer.android.com/reference/androidx/lifecycle/LiveData
Let’s understand it with an example of the Sleep tracker in HealthifyMe app:

In the red box, we have sleep goal(8h), and how much the user achieved (4h).
Step 1: Define LiveData object to store data and a method to observe that data in View class.
private val sleepGoalFetchedLiveData = MutableLiveData<SleepGoalData>()fun getSleepGoal(): LiveData<SleepGoalData> = sleepGoalFetchedLiveData
Step 2: Fetch data through API call in ViewModel class, and in onSuccess() save tha data in live Data object using sleepGoalFetchedLiveData.value = t
Step 3: Define viewModel object in activity. this
refers to an instance of lifecycleOwner
.
private val sleepGoalViewModel: SleepGoalViewModel by lazy {
ViewModelProviders.of(this).get(SleepGoalViewModel::class.java)
}
We are observing Data changes in activity so activity will be notified when live data has been set.
getSleepGoal().observe(context, NonNullObserver<SleepGoalData> {
//Ui update by getting it.sleepTi
})
SleepGoalData class will contain sleep time and wake-up time. The goal will be the diff between these values.
var hourDiff =
set(getGoalHourAndMinuteDifference(sleepTime.get(), wakeTime.get()))
Using the above code we will get our sleep goal and we will set UI.
Using the above example we can see how viewModel has been used to make API calls and data storing using live data and get the update inside our activity and fragment.
Now suppose the user wants to update the sleep goal. He will click on the edit button which was inside the red box of the above screenshot. User will enter in below Screen which is SleepGoalFragment
.

Now because SleepGoalViewModel
lifecycle is bound to activity lifeCycle and fragment is part of an activity, it will listen to all the changes happening in activity and vice versa.
Users can edit sleep time and wake time. Once after editing user click on the done button, we call saveSleepGoal
API from SleepGoalViewModel.
Step 1: Define viewModel object with activity lifecycle.
private val sleepGoalViewModel: SleepGoalViewModel by lazy { ViewModelProviders.of(requireActivity()).get(SleepGoalViewModel::class.java)
}
Now on the done button click call saveGoal method of ViewModel.
btn_done.setOnClickListener {
sleepGoalViewModel.checkAndSaveGoal()
}
Step 2: Call API to save data and set updated values in live data.
Because liveData is observed into activity and ViewModel lifecycle is bound to activity, even after fragment is closed, the activity will be notified for updated value and you will get. a callback inside getSleepGoal().
getSleepGoal().observe(context, NonNullObserver<SleepGoalData> {
//Ui update by getting it.sleepTi
})
From the above example, we understood how liveData will help in data transition.
LifecycleOwner
It is an interface that is used by any class that has an android lifecycle. Both ViewModel and LiveData can bind to the lifecycle owner.
Many Android components and libraries require to subscribe, initialize, unsubscribe and stop the components. Failing to do that can lead to a memory leak.
Step 1: Implement LifecycleObserver
to make lifeCycle aware component.
The listener will start observing as soon as the lifecycle owner is created and will stop once the lifecycle owner is destroyed. Now activity. doesn’t need to. handle all the state it will be done by life cycle owner once it is added.
You can query the current lifecycle state inside your LifecycleOwner
such as activity using getLifecycle().getCurrentState()
Conclusion
As many actions in Android applications are lifecycle driven, using lifecycle-aware components that react to lifecycle status changes to perform actions helps produce better-organized, decoupled, and light-weight components, which in turn goes a long way to building a more maintainable and testable codebase.
Thank you for reading. 👏 I hope you’ve found this article helpful. Your claps are really appreciated to help others find this article 😃 .
