LiveData는 관찰 가능한 데이터 홀더 클래스입니다. 관찰 가능한 일반 클래스와 달리 LiveData는 생명 주기를 인식합니다. 즉, 액티비티, 프래그먼트, 서비스 등 다른 앱 구성요소의 생명 주기를 고려합니다. 수명 주기 인식을 통해 LiveData는 활동 수명 주기 상태에 있는 앱 구성요소 관찰자만 업데이트합니다.
라고 공식 문서에 적혀있는데, 말이 조금 난해하다. 쉽게 이해해보도록 하자.
Data Holder Class : 동작을 거의 하지 않고, 데이터만 가지고 있는 클래스
LiveData
는 기본적으로 자신이 옵저버의 역할을 수행한다. 변경이 감지되면 자신에게 붙은 구독자들에게 변경이 되었습니다!
하고 알림을 주고, 구독자들은 이에 따라 여러 행동을 할 수 있게 된다.
(이해가 되지 않는다면, 리액티브 프로그래밍의 기초인 옵저버 패턴을 참고하자.)
그런데, LiveData
는 기본적인 옵저버 기능말고도 안드로이드에 특화된 기능을 제공한다. 바로 안드로이드의 생명주기를 인식하는 것인데, 생명주기를 인식하면 어떤 이 점을 갖게되는 걸까?
간단하게 생각해보자. 화면이 사용자의 휴대폰에 띄워져 있지 않은데도 데이터가 필요할까? 당연히 필요하지 않을 것이다. 그럼에도 불구하고 데이터를 계속해서 전달하고 있다면, 메모리 누수가 발생하여 성능 저하가 발생할 것이다. LiveData
는 이러한 단점을 보완하고, 메모리 누수 발생을 방지한다.
🧐 어떻게 생명주기를 인식하는거야?
LifeCycleOwner
가 안드로이드의 생명 주기를 인식한다. 이 인터페이스는 Activity
, Fragment
에 기본적으로 구현되어 있으며, getLifeCycle()
메소드를 통해 LifeCycle
객체를 가져온다.
추가적으로, 구글에서 이야기하는 LiveData
사용의 장점은 다음과 같다.
LiveData
객체 확장이 가능하다.우선 위와 같은 형태의 XML 파일을 만들어준다. 우리는 여기서 EditText
에 값을 넣고, Edit
버튼을 클릭하면 위의 TextView
가 실시간으로 변하는 코드를 넣을 것이다.
class EditUserProfileActivity : AppCompatActivity() {
var userLiveData = MutableLiveData<User>() // LiveData 선언
private val binding : ActivityEditUserProfileBinding by lazy {
ActivityEditUserProfileBinding.inflate(layoutInflater)
} // View Binding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
userLiveData.observe(this) { // LiveData 변화 감지시 움직임
binding.tvNickname.text = it.nickname
binding.tvName.text = it.name
Toast.makeText(this, "변경이 감지되었습니다.", Toast.LENGTH_LONG).show();
}
binding.btnEdit.setOnClickListener {
var userData = userLiveData.value
val setNickName = binding.edtNickname.text.toString()
val setName = binding.edtName.text.toString()
userData = User(setNickName, setName)
userLiveData.postValue(userData) // LiveData로 값 전송
}
}
}
코드 자체는 매우 간단하다.
userLiveData.observe(this) { // LiveData 변화 감지시 움직임
binding.tvNickname.text = it.nickname
binding.tvName.text = it.name
Toast.makeText(this, "변경이 감지되었습니다.", Toast.LENGTH_LONG).show();
}
이 부분이 LiveData
의 핵심인 부분이다. observe
메소드에 인자로 주어진 this
가 위에서 이야기한 LifeCycleOwner
로, 이 녀석을 통해 컴포넌트의 생명주기를 인식하는 것이다.
두 번째 인자로 Observer
객체를 넘겨주고, 변화가 일어났을 때 할 행동을 설정한다. 위의 코드에서는 TextView
의 값을 바꿔주는 것으로 코드를 작성하였다.
Mutable
: 변경 가능한
즉, MutableLiveData
는 변경 가능한 LiveData
를 의미한다. 쉽게 이야기해 LiveData
계의 var
라고 보면 된다. MutableLiveData
의 값을 변경하는 방법은 두 가지가 있고, 두 방법을 사용하지 않으면 값의 변경을 감지하지 못하니 꼭 이 방법을 사용하도록 하자.
setValue()
: Main Thread에서 작업이 일어나며, 동기적으로 처리된다.postValue()
: Background Thread에서 작업이 일어나며, 비동기적으로 처리된다.비동기적으로 처리될 때 순서 보장이 안된다는 것은 다들 아시죠? 😉
😯 왜 이렇게 둘을 나눠놓았을까?
이는 ViewModel, View의 역할을 분리하기 위함이다.
이에 관한 자세한 내용은 나중에 ViewModel에 관한 포스팅을 작성할 때 담도록 한다.
참고 및 출처
Android LiveData의 사용법과 내부 코드를 통한 UI 처리, 중복 처리 등 살펴보기
안드로이드 공식 문서