새소식

android studio

[android] ViewBinding vs DataBinding ?

  • -

ViewBinding, DataBinding을 알아보기 전 이 그림을 보자.

Databinding이 ViewBinding의 역할도 해주고 있네??

근데 왜 ViewBinding에 대해서도 알아야하는거지?라고 생각할 수도 있다.

 

그 이유에 대해서 알아보겠다. 

 

ViewBinding?

1) ViewBinding 사용하게 된 이유

기존에는 xml에 있는 textview를 참조하기 위해 findViewById를 사용하여 접근하였다. 

val textview  = findViewById<TextView>(R.id.tv)
        textview.text = "입력"

findViewById를 사용하여 접근하려면 참조할 때마다 하나씩 선언해주어 참조해야하는데 매우 번거롭다.

또한 findViewById는 Null값을 처리하지 못하여 Null point Exception을 발생시킬 수 있고, 예를들어 textView의 타입을 <imageView>라고 잘못 적어서 캐스팅하면 cast exception이 발생할 수 있다. 

 

이를 방지해주기 위해 null safety, Type safety가 보장된 ViewBinding을 사용한다. 

 

**kotlin extensions라는 것도 있었지만, 여러 이유로 deprecated 되었다.

1. 코틀린에서만 사용하므로, 자바에서는 사용불가

2. 일부 상황에서 뷰를 찾을 수 없는 오류 발생

3. 어디서나 뷰를 호출할 수 있기에, 잘못된 참조로 앱이 강제종료 당할 수 있음

 

2) ViewBinding

ViewBinding을 사용하면 뷰와 상호작용하는 코드를 쉽게 작성할 수 있다.

View Binding은 각 XML 레이아웃 파일의 Binding 클래스를 생성한다.

Binding 클래스의 인스턴스에서 레이아웃에 ID가 있는 모든 뷰의 직접참조를 할 수 있다.

 

  • Null 안정성 : 개발자가 실수로 유효하지 않은 id를 사용했을 때 null 오류가 방지
  • Type 안정성 : TextView의 타입을 잘못 적어서 캐스팅하면 cast exception이 발생할 수 있다.
  • 속도가 findViewById 보다 빠르다.

 

3) VIewBinding 사용방법 

build.gradle 추가

//사용하는 Android Studio 버전이 3.6 ~ 4.0
android {
	...
    viewBinding{
      enabled true
      }
    }

//사용하는 Android Studio 버전이 4.0 이상일시
android {
	...
    buildFeatures {
    	viewBinding = true
    	}
    }

MainActivity에서 ViewBinding 사용 

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	val binding = ActivitymainBinding.inflate(layoutInflater)
        setContentView(binding.root)
	binding.textview1.text = "Hello,World!"

 


DataBinding? 

1) DataBinding

UI 요소와 데이터를 프로그램적 방식으로 연결하지 않고, 선언적 형식으로 결합할 수 있게 도와주는 라이브러리를 말한다.

 

- 프로그램적 방식

프로그램적 방식은 흔히 아는 findViewById와 ViewBinding 방법을 사용하여 선언을 해준 것이다.

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</androidx.constraintlayout.widget.ConstraintLayout>
// findViewById 방식
val textview = findViewById<TextView>(R.id.sample_test)
sample_test.text = "안녕"
// ViewBinding 방식
binding.sample_test.text = "안녕"

 

2) DataBinding 사용하기 (선언전 방식) 

build.gradle 추가

// Android Studio 3.6 ~ 4.0
adroid{
	...
    dataBinding {
    	enabled true
        }
}
// Android Studio 4.0 이상
adroid{
	...
    buildFeatures {
    	dataBidning = true
        }
}

 

activity_main.xml  <layout> 루트 태그 사용 

<?xml version="1.0" encoding="utf-8"?>
<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">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width= "match_parent"
        android:layout_height= "match_parent"
        tools:context=".MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    
</layout>

DataBinding 을 사용하는 xml 리소스는 <layout> 루트 태그로 시작하여야 한다.

 

MainActivity DataBinding사용 

class MainActivity : AppCompatActivity(){
	private lateinit var binding : ActivityMainBinding
    
    override fun onCreate(savedInstanceState : Bundle?){
    	super.onCreate(savedInstanceState)
        
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main) 
    }
}

DataBindingUtil class 의 객체를 생성하고,

기존의 setContentView() 를 DataBindingUtil.setContentView() 로 대체한다.

이제, data binding 을 사용하여 layout 을 관리할 수 있다.

 

View에 보여줄 data class 생성 

data class User(
	val name : String,
        val age: Int
)

data 객체를 view 와 bind 하기 위해서, User 라는 이름의 data class 를 하나 만든다.

 

activity_main.xm에 <data> 요소 작성

<?xml version="1.0" encoding="utf-8"?>
<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>
    	<import type = "android.view.View"/>
        <variable
        	name = "User"
                type = "com.es.databinding.User"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width= "match_parent"
        android:layout_height= "match_parent"
        tools:context=".MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text = "@{user.name}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    
</layout>

<data> 태그는 <layout> 에서 사용할 변수를 정의하는데 사용된다.

나는 User 라는 data class 객체를 사용할 것이기 때문에 name 이 user 인 variable 을 하나 선언해 주었다. 

레이아웃 내의 표현식은 "@{}" 구문을 사용하여 속성(attribute properties) 에서 작성된다.

나는 TextView 의 텍스트를 user 변수내의 name 프로퍼티로 설정했다. 

 

Activity 에서 User 객체 초기화

class MainActivity : AppCompatActivity(){
	private lateinit var binding : ActivityMainBinding
    
    override fun onCreate(savedInstanceState : Bundle?){
    	super.onCreate(savedInstanceState)
        
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main) 4
        
        val user = User("올라프", 23)
        binding.user = user
    }
}

User 객체를 초기화하여 binding 객체의 data source 를 set 해준다. 

 

 

3) DataBinding 사용 이유 

  • xml에 데이터를 binding 하여 불필요한 코드를 줄일 수 있다. 
    실제 사용할 때 DTO나 데이터 클래스에 연결된 클래스 변경 시 연결된 많은 View가 한번에 변경되기 때문에 굉장히 편해진다.
    또 DataBinding과 같이 BindingAdapter를 이용해 ImageView에 이미지 로딩 라이브러리를 이용해서 이미지 출력을 쉽게하고, LiveData를 사용하면 Data가 실시간으로 변경될 때 View도 같이 변경되어 MVVM 패턴 구현 시 편리해진다.
  • Databinding을 사용하면 findViewById()를 쓰지 않아도 xml에 만든 View들을 자동으로 만들어 준다.
  • Data가 바뀌면 알아서 바뀐 Data로 View를 변경하게 할수도 있다. (Observe 사용 시)
  • RecyclerView에서 각각의 item을 세팅 해주는 작업도 XML에서 다 써주면 알아서 값이 들어간다.
  • 구글에서 DataBinding 사용을 권장한다. 

앞서 첫번째 그림에서 보여준 것과 같이 DataBinding은 ViewBinding의 역할도 수행하고

추가로 동적 UI 콘텐츠 선언, 양방향 데이터 binding도 지원한다.

 

하지만 ViewBinding이 DataBinding보다 퍼포먼스 효율이 좋고 용량이 절약되는 장점이 있다.
단순히 findViewById를 대체하기 위해 Binding을 쓴다면 ViewBinding 사용을 권장한다. 

 

 

'android studio' 카테고리의 다른 글

[android] Handler & Looper  (0) 2023.07.24
[android] android service?  (0) 2023.07.21
[android] ViewModel란?  (0) 2023.07.09
[android] Livedata란? (feat.ViewModel)  (0) 2023.07.09
[Android] Thread와 Coroutine의 차이  (0) 2023.07.04
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.