Android

[Android] 안드로이드 ViewBinding 완벽 가이드: 개념, 도입 배경, 사용법, 동작 방식 및 컴파일 위치

yujinius 2024. 11. 9. 22:25
안드로이드 ViewBinding 완벽 가이드: 개념, 도입 배경, 사용법, 동작 방식 및 컴파일 위치


안드로이드 개발에서 findViewById 메서드는 XML 레이아웃에 정의된 뷰를 코드에서 참조하기 위해 오랫동안 사용되어 왔다. 그러나 findViewById는 런타임 뷰 트리를 탐색하여 원하는 뷰를 찾는 구조로 작동하기 때문에 성능에 영향을 미치고, 타입 안전성 및 null 안전성 문제를 유발할 수 있다.

이에 대한 자세한 내용은 아래의 글을 참고하자.

https://yujinius45.tistory.com/124

 

[Android] 안드로이드에서 findViewById 완벽 가이드: 사용법, 동적 뷰 조작, 문제점과 해결 방법

안드로이드에서 findViewById 완벽 가이드: 사용법, 동적 뷰 조작, 문제점과 해결 방법목차findViewById 개요findViewById 기본 사용법: MainActivity에서 뷰에 접근하기동적 뷰 삽입 및 삭제 실습Layout Inspector

yujinius45.tistory.com

 

이를 해결하기 위해 안드로이드 팀은 ViewBinding 기능을 도입하였다. 이 글에서는 ViewBinding의 개념, 도입 배경, 사용법, 동작 방식, 컴파일된 파일의 위치, 그리고 실습을 단계별로 다뤄보겠다.


목차

  1. ViewBinding이란 무엇인가?
  2. ViewBinding 도입 배경
  3. ViewBinding의 사용법
    • 3.1. ViewBinding 활성화
    • 3.2. Activitiy에서 ViewBinding 사용
    • 3.3. Fragment에서 ViewBinding 사용
  4. ViewBinding 동작 방식
  5. 컴파일된 바인딩 클래스 위치 확인
  6. ViewBinding 파헤치기
  7. 마무리 및 요약

1. ViewBinding이란 무엇인가?

    • ViewBinding은 2019년에 Android Studio 3.6과 함께 안드로이드 Jetpack의 일부로 공식 도입되었다. 이는 안드로이드 개발의 효율성과 안전성을 높이기 위한 안드로이드 팀의 주요 개선 사항 중 하나로, findViewById의 단점을 보완하고 코드의 가독성과 유지보수성을 강화하기 위해 추가되었다.
 

Android Studio 3.6 Canary 11 available

Android Studio 3.6 Canary 11 is now available in the Canary and Dev channels. If you have Android Studio set to receive updates on the  C...

androidstudio.googleblog.com

 

  • ViewBinding은 안드로이드에서 뷰와 상호작용하는 코드를 더 간단하고 안전하게 작성할 수 있도록 지원하는 기능이다. 모듈에서 ViewBinding을 활성화하면, 해당 모듈 내 XML 레이아웃 파일마다 자동으로 바인딩 클래스가 생성된다. 이 클래스는 해당 레이아웃 파일 내 모든 뷰에 대해 타입 안전한 참조를 제공하여 findViewById의 대안으로 사용된다.

2. ViewBinding의 도입 배경

기존 findViewById 방식은 다음과 같은 문제를 가지고 있었다:

  • 런타임 뷰 트리 탐색으로 인한 성능 문제: findViewById는 ID가 일치하는 뷰를 찾기 위해 전체 뷰 트리를 순회하므로, 복잡한 레이아웃에서 성능 저하를 초래할 수 있다.
  • 타입 안전성 부족: findViewById는 View 타입을 반환하므로, 원하는 뷰 타입으로 캐스팅해야 한다. 잘못된 캐스팅으로 인해 런타임 오류가 발생할 수 있다.
  • Null 안전성 부족: XML 레이아웃에 해당 ID가 없는 경우 findViewById는 null을 반환한다. 이를 처리하지 않으면 NullPointerException이 발생할 수 있다.
  • 코드의 복잡성 증가: 여러 뷰에 접근해야 하는 경우, 각 뷰마다 findViewById를 호출해야 하므로 코드가 길어지고 유지보수성이 떨어진다.

ViewBinding은 이러한 문제들을 해결하며, 컴파일 타임에 뷰 참조를 생성해 타입과 null 안전성을 보장하고 코드의 간결성과 유지보수성을 크게 향상시킨다.


3. ViewBinding의 사용법

3.1. ViewBinding 활성화

모듈 수준의 build.gradle(:app) 파일에서 ViewBinding을 활성화하려면 다음과 같이 설정한다:

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

이렇게 설정하면 해당 모듈의 모든 XML 레이아웃 파일에 대해 바인딩 클래스가 생성된다. 특정 레이아웃 파일에 대해 바인딩 클래스를 제외하려면, 해당 레이아웃의 루트 뷰에 tools:viewBindingIgnore="true" 속성을 추가한다:

<LinearLayout
    ...
    tools:viewBindingIgnore="true">
    ...
</LinearLayout>

3.2. Activity에서 ViewBinding 사용

1. Activity의 XML 레이아웃 파일 준비

 

  • activity_main.xml 파일을 준비하고 TextView와 Button을 추가해보자.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="18sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Change Text" />

</LinearLayout>

 

 

2. Activity에서 ViewBinding 사용

  • MainActivity 클래스에서 ViewBinding을 통해 TextView와 Button에 접근하고 버튼을 클릭할 때 텍스트가 변경되도록 구현한다.
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 뷰에 접근하여 사용
        binding.textView.text = "Welcome to Android!"

        binding.button.setOnClickListener {
            binding.textView.text = "Button Clicked!"
        }
    }
}

 

이렇게 하면 findViewById 없이도 뷰에 직접 접근할 수 있으며, ActivityMainBinding이 이미 TextView와 Button에 대한 참조를 제공하므로 런타임 탐색 과정 없이 성능이 개선된다.

3.3. Fragment에서 ViewBinding 사용

Fragment에서 ViewBinding을 사용할 때는 뷰의 생명 주기를 고려하여 onCreateView에서 바인딩 객체를 초기화하고, onDestroyView에서 해제해야 한다.

class MainFragment : Fragment() {
    private var _binding: FragmentMainBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentMainBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

 

이렇게 함으로써 Fragment의 뷰 생명 주기 내에서 메모리 누수를 방지할 수 있다.


4. ViewBinding의 동작 방식

ViewBinding은 컴파일 타임에 XML 레이아웃 파일에 대응하는 바인딩 클래스를 자동 생성한다. 예를 들어, activity_main.xml 파일이 있다면, ActivityMainBinding 클래스가 생성되며, 이 클래스는 activity_main.xml에 정의된 뷰에 직접 접근할 수 있는 속성을 포함한다. 이렇게 컴파일 타임에 생성된 참조를 통해 런타임 뷰 트리 탐색 과정을 생략하고 성능을 개선할 수 있다.

동작 방식 확인하기

  1. ActivityMainBinding을 사용하는 MainActivity 코드로 프로젝트를 빌드하면, 바인딩 클래스가 생성된다.
  2. 생성된 바인딩 클래스는 뷰의 ID와 일치하는 필드를 포함하며, 이를 통해 TextView, Button 등에 직접 접근할 수 있다.

5. 컴파일된 바인딩 클래스의 위치 확인

ViewBinding 클래스를 확인하려면 빌드 후 다음 경로에서 찾을 수 있다.

app/build/generated/data_binding_base_class_source_out/{build_variant}/out/{패키지 경로}/ActivityMainBinding.java

 

여기서 {build_variant}는 프로젝트의 빌드 변형에 따라 다르다. 예를 들어, debug 빌드로 컴파일했다면 경로는 debug/out 폴더에 위치하게 된다. 이 경로에서 실제 생성된 바인딩 클래스를 열어보면, 컴파일 타임에 생성된 ViewBinding의 내부 구조를 확인할 수 있다.

 


ViewBinding 파헤치기

위의 ViewBinding 사용법을 기반으로 아래의 동작 원리 파헤치기를 읽으면 ViewBinding과 findViewById의 차이를 이해하는 데에 도움이 된다.

실습을 해보면서 작성해둔 글이기에 안드로이드 스튜디오에서 함께 해보면 좋다.

https://yujinius45.tistory.com/126

 

[Android] ViewBinding 동작 원리 파헤치기

안드로이드 ViewBinding 동작 원리 파헤치기이전 포스팅에서는 findViewById의 내부 동작 원리를 살펴보았다.https://yujinius45.tistory.com/125 [Android] findViewById 동작 원리 파해치기안드로이드 findViewById 동작

yujinius45.tistory.com

 

혹시 위의 글을 읽지 않고 넘어왔는가? 아래의 참고 정보는 읽고 넘어가길 바란다.

 

참고 : DataBinding과 ViewBinding의 관계

  • ViewBinding이 활성화되면 바인딩 클래스는 databinding 폴더에 생성된다. 이는 ViewBinding이 DataBinding보다 나중에 등장했으나, 두 기능이 Jetpack 라이브러리에 함께 통합되어 있는 구조이기 때문이다.

마무리 및 요약

ViewBinding은 findViewById의 단점을 보완하여 타입 안전성과 null 안전성을 보장하면서도 런타임에 뷰 트리를 탐색하지 않고 직접 접근할 수 있는 성능 개선을 제공한다. 특히, 복잡한 뷰 계층 구조에서는 성능 이점을 더욱 실감할 수 있다.

ViewBinding의 주요 장점 요약

  • 성능 개선: 컴파일 타임에 참조를 생성해 런타임 탐색 과정 생략
  • 타입 안전성: 자동으로 생성된 타입 참조를 통해 안전한 뷰 접근 가능
  • Null 안전성: Null 가능성 제거로 인해 안정성 보장
  • 코드 간결성: findViewById 반복 호출을 줄여 코드 가독성과 유지보수성 향상

다음 글에서는 DataBinding을 다룬 후 ViewBinding과의 차이점을 소개하고, 프로젝트에 맞는 바인딩 방식을 선택하는 방법을 함께 살펴보겠다.