Android Data Binding: Under the Hood (Part 2)
By: Niharika Arora
Tags: Mvvm Databinding, Women In Tech, Data Binding, Android Data Binding, AndroidDev

Click Events & Data Update

Let's say I have a textView and a button in my XML. On button click, I want to update my text. Here comes the role of ViewModel (If you are working with MVVM, you are already aware of it.), where we write all our business logic. This is my XML:

And, This is my MainViewModel,

I updated my MainActivity to use ViewModel,

Note: To use a LiveData object with your binding class, you need to specify a lifecycle owner to define the scope of the LiveData object.

Now, Whenever a user clicks the button, the count is incremented and as this count is a LiveData and has been observed in XML by the `count_textView`, you will always see the latest updated value.

Wow, So Easy it is. But, How exactly is this happening? How does DataBinding class know that this view needs to be updated?

Well, We have the answer,

In our ActivityMainBinding class, you will find this:

You can see a field named `_localFieldCount`. This parameter now holds a value of 1 because now the XML is having one view which is observing for any changes.

In the case of static data, where we just rendered the model values, this `_localFieldCount` was 0 as no view was observing for any changes. (Check the previous article for reference.)

And this class ActivityMainBinding extends ViewDataBinding, so it calls the Parent class constructor, where we have a WeakListener array which is nothing but an array of Weak reference objects which do not prevent their referents from being made finalizable, finalized, and then reclaimed. The best part is we don’t need to worry about their cleanups. :-)

So whenever an activity sets a lifecycle owner, which is in our case is Activity Scope, ViewDataBinding class registers for a listener i.e onStartListener. Whenever the activity comes in onStart state, binding class starts executing the bindings.

@OnLifecycleEvent(Lifecycle.Event.ON_START)

public void onStart() {

ViewDataBinding dataBinding = mBinding.get();

if (dataBinding != null) {

dataBinding.executePendingBindings();

}

}

In our ActivityMainBindingImpl, we have our executeBindings, which takes the count value from ViewModel and passes to updateLiveDataRegistration method.

This updateLiveDataRegistration asks to create a weak listener for the livedata variable we passed and then start listening for the updates. (This internally sets the same lifecycleOwner for the liveData as well) This localFieldId is set to 0 in this case.

Now when the user clicks the button, `onChanged()` method from our LiveDataListener gets called,

This eventually calls our own implementation of `onFieldChange()`, which looks like this,

As we have LiveData with name ‘count’, binding class creates a similar name combing the viewmodel and variable name i.e, viewModelCount and the same way all the methods related to it follows.

Inside this onChangeViewModelCount() method, we have `mDirtyFlags`(a long value) which is getting updated, returns true and requests for rebinding which will call execute pending bindings and get views updated on the screen.

synchronized(this) {

mDirtyFlags |= 0x1L;

}

This process keeps on repeating every time we click our button.

So this is how the click events and updates are handled by DataBinding class.

For reference, you can find my DataBinding sample here: