회사에서 jetPack을 적용하기 위해 공식문서와 여러가지를 참조해서 ViewModel을 처음 생성할 때 저는 Live Data만 알고 있었습니다. 그래서 ObservableField가 무엇인지 알지 못했습니다!
그런데 제가 어쩌다 다른 회사에 지원을 하게 되었고, 그 회사의 사전 면접에서 LiveData와 ObservableField의 차이점이 무엇인지에 대해서 물어보는 것이었습니다. 아예 ObservableField에 대한 정보가 없던 저는 당연히 제대로 대답하는 것이 불가능했고!(안타깝지만 모르는 것을 아는 척하는 것보다는 모른다고 대답하는 것이 더 매끄러운 것 같아서 그냥 모른다고 대답했습니다.) 이후 저는 블로그에 꼭 글로 남겨둬야겠다는 다짐을 하게 되었습니다.
덕분에 이번 게시글의 주제는 LiveData와 ObservableField이 무엇인지, 각기 다른 두 개의 형식은 어떤 차이점이 있는지 입니다!
LiveData의 경우 제가 이미 한 번 그 주제를 통해 글을 썼던 적이 있습니다.
https://no-dev-nk.tistory.com/20?category=876493
위의 글을 통해 LiveData가 무엇인지 작성을 한 적이 있기 때문에 LiveData의 설명은 링크를 통해 하도록 하겠습니다.
그렇다면 ObservableField는 무엇인지 알아보겠습니다.
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
- ObservableArrayMap
- ObservableField
먼저 ObservableField라고 정의할 수 있는 클래스는 위와 같습니다. 원시적인 Boolean 타입이나 Int 타입과 같은 기본 타입들은 클래스로 따로 지원해주고, 나머지 타입(String 포함)은 ObservableField를 통해 관찰할 수 있습니다.
이러한 클래스는 LiveData처럼 xml에서 dataBinding 작업을 할 수 있습니다.
//ObservableArrayMap 코드
ObservableArrayMap<String, Any>().apply {
put("firstName", "Google")
put("lastName", "Inc.")
put("age", 17)
}
//xml 코드
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user.age)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
위의 코드는 안드로이드 공식 문서의 예제로, ObservableArrayMap이라는 옵저빙이 가능한 클래스에 데이터를 put으로 넣고 난 후, xml에서 기존 LiveData처럼 적용이 가능합니다. 이는 ViewModel에서 응용이 가능하다는 것을 의미합니다.
observableField.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
Log.d("testing", "ObservableField: ${observableField.get()}")
}
})
위와 같은 코드를 통해 xml에서 처리하지 않고 코틀린 코드에서 변경에 따른 코드를 설정하는 것 역시 가능합니다. 그렇다면 LiveData와 ObservableField가 구분되어 있는 이유가 있을 텐데, 그 차이점은 무엇인지 알아보겠습니다.
LiveData와 ObservableField의 차이점
먼저 LiveData의 가장 큰 장점은 수명주기를 인식한다는 것입니다. 이는 파라미터로 받는 Lifecycler을 통해 데이터바인딩 된 UI가 현재 죽어있는 상태인지 화면에 보이고 있는 상태인지를 확인할 수 있다는 것을 의미합니다. 그러나 ObservableField는 수명주기를 인식하지 않습니다. 그렇기 때문에 UI가 종료된 이후 데이터를 수정해도 옵저버의 동작이 이루어지게 됩니다. 그러나 LiveData는 UI가 동작하지 않는 상황에서는 옵저버가 이미 소멸한 상태이므로 옵저버가 동작하지 않습니다.
ObservableField를 사용할 때 옵저버의 유지로 인한 리소스 낭비를 제어하기 위해서는 UI의 종료에 따라 수동으로 옵저버를 제어줘야 합니다.
그렇다면 ObservableField는 LiveData의 하위호환이지 않나라는 생각이 듭니다. 실제로 ObservableField가 나온 이후 LiveData가 AAC에 녹아들어 출시 되었기 때문에 하위호환이라고 해도 크게 틀린 말이 아닐 수 있습니다.
결국 UI를 구성하는 과정 중 가장 중요한 것은 데이터가 UI와 같이 태어났다 사라지는 것인데, 이를 해결하기 위해서 lifecycle을 변수에게 준 것이기 때문에 안드로이드 공식 developer에서도 LiveData의 사용을 권장하고 있습니다.
물론 특정 상황에서는 ObservableField를 쓰게 되는 일이 발생할 수도 있을 것 같습니다. 테스트나 여러가지 이유때문에 UI와 별개로 코드가 동작해야 하는 경우가 존재한다면(변수의 동작을 관찰해야 하지만 그것이 UI와 관련된 사항이 아닌 경우도 배제할 수 없습니다!) 충분히 과거의 코드라고 하더라도 사용하게 될 것입니다.
면접 때문에 검색하게 된 ObservableField라는 클래스였습니다. 관찰 가능한 변수를 사용할 때 부터(dataBinding을 적용할 시기부터) 이미 LiveData를 사용할 수 있었고, 안드로이드에서 권장하는 코드였기도 하고, 회사 사수께서 사용하라고 해서 다른 경우의 수를 따져보지 않았기 때문에 면접에서는 잘 대답하지 못했습니다.
면접을 본 덕분에 이렇게 또 제가 알고 있는 상식의 구멍을 조금이나마 메꿀 수 있어서 도움이 되었다고 생각하고 있습니다.(하지만 면접에서 떨어지는 경험은 매번 할 때마다 좋지는 않더라구요.)
'안드로이드 > 코틀린' 카테고리의 다른 글
recyclerView 스크롤 이벤트 작성 (0) | 2021.12.29 |
---|---|
코틀린 - apply, with, let, also, run(Scope Functions) (0) | 2021.08.24 |
(android - jetPack) bindingAdapter (0) | 2021.06.06 |
Gson의 기본적인 사용법(with kotlin) (0) | 2021.05.29 |
(android) skydoves - Balloon (0) | 2021.05.27 |
댓글