View Binding
목표
- 안드로이드에서 View 에 접근하는 방법들을 보고 차이를 이해한다.
- View binding 의 사용법을 익힌다.
View Binding 이란?
View binding 은 안드로이드에서 view 에 접근하는 방법 중 하나다. View binding 을 제공하기 이전에 이미 Data binding 이란 기능을 지원하고 있었지만, 많은 개발자들이 data binding 의 모든 기능을 사용하지 않고, view 에 접근하기 위해서만 사용하는 것을 보고 안드로이드 스튜디오 3.6 버전에서 추가된 기능이다. View 에 접근하는 방법은 몇 가지가 있는데, 이를 도표로 정리하면 아래와 같다.
해당 도표에 있는 3가지 측정 기준은
- Elegrance : 코드를 간결하게 쓸 수 있는가
- Compile time safety : 컴파일 타임에 안전한가
- Build speed imact : 빌드 속도가 빠른가
이다. 그래서 어떤걸 선택해야 한다는건지…? 위의 기준을 토대로 기능들을 비교해보자.
findViewById
- 뷰의 갯수만큼 코드를 추가해줘야 하므로 간결함이 떨어진다.
- 잘못된 id 를 넘겼을 때, null pointer exception 이 발생한다. (null safety 하지 않음)
Butter Knife
- findViewById 에 비해 간결하긴 하지만, 여전히 보일러 플레이트 코드가 발생한다.
- 2020년 3월에 deprecated 됐다.
Kotlin Synthethic
- 같은 id 를 가진 다른 뷰에 접근하는 실수가 발생할 여지가 있다.
- kotlin 만 사용 가능하다.
- 안드로이드 스튜디오 4.1 버전 기준으로 deprecated 됐다.
View Binding
- View 를 직접 참조하는 클래스를 생성하여 유효하지 않은 view id 를 참조할 수 없기 때문에 null safety 하다. 다만, 같은 레이아웃 중 일부에만 존재하는 view 는 @Nullable 로 표시된다.
- 바인딩 클래스 view 필드 유형이 xml 파일에서 참조하는 view 와 동일하기 때문에 class cast exception 으로부터 안전하다.
- 컴파일 속도가 빠르다.
Data Binding
- View 를 직접 참조하는 클래스를 생성하여 유효하지 않은 view id 를 참조할 수 없기 때문에 null safety 하다. 다만, 같은 레이아웃 중 일부에만 존재하는 view 는 @Nullable 로 표시된다.
- 바인딩 클래스 view 필드 유형이 xml 파일에서 참조하는 view 와 동일하기 때문에 class cast exception 으로부터 안전하다.
- View binding 에 비해 컴파일 속도가 느리다.
- 동적 UI 컨텐츠를 구성할 수 있다.
- Two-way data binding 을 지원한다.
결론적으로, View binding 과 Data binding 의 차이를 비교해보고 상황에 맞도록 사용하면 된다. 답정너
View Binding vs Data Binding
간단하게 둘의 관계를 정리하면 Data binding = View binding + Binding data to views 이다.
- View Binding : 빌드 속도 우세, 앱 용량 크기가 상대적으로 작음, xml 에 layout 태그를 감싸줄 필요가 없어서 사용이 용이함, 데이터 바인딩 기능 사용 못함
- Data Binding : 빌드 속도 열세, 앱 크기가 View binding 을 이용하는 것 보다 커짐, xml 의 최상단에 layout 태그로 감싸줘야함, 데이터 바인딩 기능을 이용한 동적 UI 설계 가능
사용법
Setup
앱의 build.gradle 에서 View binding 을 사용할 수 있도록 설정해주자.
// 안드로이드 스튜디오 4.0 이상
android {
buildFeatures {
viewBinding = true
}
}
안드로이드 스튜디오 4.0 부터 param 의 위치가 buildFeatures 로 변경됐다. 그보다 미만 버전에서는 아래와 같이 설정하면 된다.
// 안드로이드 스튜디오 4.0 미만
android {
viewBinding {
enabled = true
}
}
위와 같이 설정을 완료하면 레이아웃 파일에 해당하는 바인딩 클래스가 생성된다. 바인딩 클래스의 네이밍 규칙은 xml 의 이름을 upper camel case 로 변환한 뒤 Binding 이 붙는 형태이다.
main_activity.xml → MainActivityBinding
first_fragment.xml → FirstFragmentBinding
item_content.xml → ItemContentBinding
Activity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 바인딩 클래스의 inflate 메서드를 호출하여 인스턴스 생성
binding = ActivityMainBinding.inflate(layoutInflater)
// 바인딩 인스턴스에서 getRoot 메서드를 호출하여 해당 뷰를 스트린에 띄움
setContentView(binding.root)
// 바인딩 클래스에 id 가 textView 인 Text view 에 다음과 같이 접근할 수 있다.
binding.textView.text = "Hello View Binding!"
}
}
Fragment
class FirstFragment : Fragment() {
private var _binding: FragmentFirstBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentFirstBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.textView.text = "Hello View Binding!"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
프래그먼트에서 뷰 바인딩을 사용할 때, Fragment 는 View 보다 오래 존재하기 때문에 onDestroyView() 에서 바인딩 클래스 인스턴스의 레퍼런스를 null 로 정리해줘야 합니다. (안해주면 메모리릭 남. 님 앱 펑! ㅇㅇ) 그렇기 때문에 프래그먼트에서 뷰 바인딩을 사용할 때는 위와 같이 추가적인 코드가 들어가게 됩니다.
결론
뷰에 접근하기 위해서는 View binding 과 Data binding 의 차이를 숙지하고, 상황에 맞는 방법을 사용하는 것이 좋으며, 속도와 간결함을 중시한다면 View binding 을 고려해보는 것이 좋습니다.
댓글남기기