본문 바로가기
Android/DataBinding

[Android] DataBinding에 대한 고찰 (1) - DataBinding은 어떻게 생성되는가?

by 태크민 2025. 1. 8.

위 포스팅은 DataBinding에 대한 기본적인 이해가 있는 독자를 염두에 두고 작성되었습니다.

 

DataBinding이란?

데이터 바인딩은 선언적 형식으로 레이아웃의 컴포넌트와 앱의 데이터 결합을 지원하는 라이브러리이다. 2015년 Android Dev Summit에서 처음 발표되어 지금까지 안드로이드 앱을 구현할 때 흔히 사용되고 있다.

 

우리는 DataBinding을 적용한 FragmentActivity가 포함된 프로젝트를 빌드할 때, DataBinding 클래스 또는 DataBinding Impl 클래스가 생성되는 과정을 경험했을 것이다. 그렇다면 왜 이러한 클래스들이 생성되는지, 그 원리가 무엇인지 함께 살펴보자.

 

 

DataBinding 객체 생성 (Abstract Class)

DataBinding은 바인딩을 생성하고, 기타 속성들을 설정하기 위해 내부적으로 Annotation processor을 사용한다.

 

다음 DataBinding 과 결합한 xml 소스가 있다고 가정하자.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="user"
            type="com.sample.myapplication.User" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout/>
    <!-- UI layout's root element -->
</layout>

 

빌드 시 Annotion Proccessor프로젝트에서 <layout> tag를 검색하고, 만약 <layout> tag가 있다면, 레이아웃의 변수 및 View들에 접근하기 위해 Binding Class를 생성한다.

 

정확히는 ViewDataBinding의 하위 클래스인 Binding Class가 추상클래스(abstract class)로 생성되며, 이는 build/generated/data_binding_base_class_source_out 폴더에 생성이 된다.

(그래서 우리가 데이터 바인딩을 사용하여 빌드를 했을 때, ActivityMainBinding와 같은 클래스를 볼 수 있었던 것이다.)

 

ActivitiyMainBinding에서 우리가 위 코드에서 작성했던 <data>에 선언한 user class 변수에 대한 @Bindable 어노테이션을 찾을 수 있는데,

@Bindable
protected User mUser;

 

이 주석은 해당 클래스가 바인딩될 것임을 DataBinding에게 알려주기 위해 선언된다.

 

 

DataBindingImpl 객체 생성 (Implementation Class)

DataBindingImpl 객체 또한, 빌드 시  Annotion Proccessor에 의해 생성되는데 한번 알아보자.

 

우리는 DataBinding을 이용해서 XML객체를 View에 바인딩하기 위해 아래와 같이 구현하게 된다.

val binding: ActivityMainBinding =
    DataBindingUtil.setContentView(this, R.layout.activity_main)

 

이렇게 생성한 ActivityMainBinding 객체 내부에는 XML에서 정의된 View에 대한 참조가 포함되며, <data>에서 정의된 변수(variable)들을 설정할 수 있는 메소드들도 제공된다.

 

또한, DataBindingUtil의 setContentView 함수를 호출하게되면, 결과적으로 내부적으로 bind()를 호출하게 되는데, 해당 메소드는 다음과 같다.

static <T extends ViewDataBinding> T bind(DataBindingComponent bindingComponent, View root,
        int layoutId) {
    return (T) sMapper.getDataBinder(bindingComponent, root, layoutId);
}

 

여기서 sMapper는 해당 레이아웃 ID에 맞는 바인딩 구현 클래스를 반환하는 역할을 하며, 이 매핑은 프로젝트 빌드 시 Annotation Processor에 의해 처리된다.

 

Annotation Processor는 DataBinding과 관련된 XML 파일을 처리하고, 이를 기반으로 Java 또는 코틀린 코드(바인딩 클래스, 바인딩 클래스 구현체)를 생성하는데,

 

먼저 이를 생성하기 위해 Layout 파일을 분석하고, layout, data, variable와 같은 DataBinding 특정 태그를 제거하는 작업을 한다. 아래와 같이 말이다.

 

간단히 말하자면 아래와 같은 데이터 바인딩 레이아웃 파일이 존재할 경우,

 

컴파일 시 모든 데이터 바인딩 관련 정보가 제거 된다.

 

 

그리고 난 후 추가된 데이터 바인딩 표현식들을 파싱하여 해당 뷰들에 값을 설정하는 Java 코드를 생성하게되는데,

이 때 생성되는 것이 ActivityMainBindingImpl 클래스이다. (이 과정에서 물론, ActivityMainBinding 클래스도 생성된다.)

 

데이터 바인딩을 처리하는 실제 메소드는 ActivityMainBindingImpl 클래스에 구현되어 있게 된다.

 

생성된 코드는 build/generated/source 디렉토리에서 확인할 수 있다.

 

변수(Variable) 설정 예시

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_main)
        val user = User("Niharika", "Software Engineer")
        binding.user = user
    }
}

 

위 코드에서 실제 ActivityMainBinding의 user variable을 설정하는 부분은 아래와 같으며,

binding.user = user

 

실제 ActivityMainBindingImpl 내부 소스에서 다음과 같이 로직이 구현되어 있다.

public void setUser(@Nullable com.sample.myapplication.User User) {
        this.mUser = User;
        synchronized(this) {
            mDirtyFlags |= 0x1L;
        }
        notifyPropertyChanged(BR.user);
        super.requestRebind();
  }

 

"mUser"는 ActivityMainBindinding의 추상 클래스에서 왔으며, 실제 설정하는 로직은 ActivityMainBindingImpl에서 구현되어 있는 것이다.

 

마치며

평소 궁금했던 내용에 대하여 포스팅을 해보았는데요.

틀린 부분이 있으면  언제든 지적 부탁드립니다.


참고자료

https://medium.com/hongbeomi-dev/data-binding-tip-4f8f7ce17baf

 

Data Binding — Tip

데이터 바인딩 라이브러리를 조금 더 잘 활용해 봅시다.

medium.com

https://proandroiddev.com/android-data-binding-under-the-hood-part-1-33b8c7adfb7c

 

Android Data Binding Under the Hood (Part 1)

Lets take a deep dive into the internal implementation of Android DataBinding.

proandroiddev.com

https://velog.io/@wantique/DataBinding

 

DataBinding

Dive in DataBinding

velog.io

https://developer.android.com/topic/libraries/data-binding/generated-binding?hl=ko&_gl=1*149xs8r*_up*MQ..*_ga*MjEwMjI5MTQ4Mi4xNzM2MzIyODE4*_ga_6HH9YJMN9M*MTczNjMyMjgxOC4xLjAuMTczNjMyMjgxOC4wLjAuMTE3NDQ2OTY2Nw..

 

생성된 바인딩 클래스  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 생성된 바인딩 클래스 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 데이터 결합 라이브러리는 사용

developer.android.com