Android Data Binding: Under the Hood (Part 2)

Niharika Arora
ProAndroidDev
Published in
4 min readDec 27, 2020

--

Image Reference

Hola folks 👋 , I’m back with part 2 of learning & understanding how Data Binding works behind the scene.

In the previous blog, we saw different alternatives to findViewById, their pros & cons and how DataBinding works under the hood with static data. If you haven’t read it yet, I would recommend to quickly go, read and come back to know more.

In this article, let's talk about the magic happening behind the background data updates and click actions.

Well, I am sure if you are reading this article, you have already set your mind to know the magic, implementation and the players behind the scene. So let’s get started and deep dive into these aspects.

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:

This is all from my side for this part. In this part, we got to know how DataBinding internally handles the events and listens for any background updates. And the best part is we don’t need to worry about the lifecycle or clearing up objects ad whenever we use Livedata, we always provide a scope through lifeCycleOwner.

In the next part, we will understand how BindingAdapter creates its magic and works behind the scene.

This is originally published here:

I hope you learned something from this article. And, If you have any suggestions/feedback, please do leave a comment so that we can all learn together. Also, You know what? you can clap 50 times if you enjoyed reading it. Stay tuned for more :)

Please feel free to reach out to me on Twitter and LinkedIn.

--

--