본문 바로가기
Android/Kotlin

LiveData 의 postValue() vs setValue() 의 차이점, 언제 사용해야 할까?

by wannagohome97 2024. 3. 29.

프로젝트를 MVVM 형태로 구현하다 보면 ViewModel 에서 LiveData 를 쓰는 경우가 많습니다.

 

보통 private 로 선언된 MutableLiveData 의 value 를 변경하고

public 으로 선언된 LiveData 의 값을 관측하는 식으로 사용합니다.

 

그런데 이 과정에서 Coroutine 을 사용하다 보면 아래 상황에서 오류가 발생합니다.

 

DB 작업을 하는 백그라운드 스레드에서 setValue 를 호출

 

그리고 이러한 오류를 마주치게 되죠

java.lang.IllegalStateException: Cannot invoke setValue on a background thread

 

setValue 메서드는 백그라운드에서 호출할 수 없다고 합니다.

 

그래서 백그라운드에서는? postValue 를 사용해야합니다.

 

하지만 postValue 는 setValue 와는 다르게 값을 '즉시 적용' 하는 개념이 아니라

아래와 같이 백그라운드에서 핸들러를 통해 setValue 를 post 해주는 형태입니다.

new Handler(Looper.mainLooper()).post(() -> setValue())

 

그렇기 때문에 postValue 이후에 바로 LiveData 의 값을 찍어보면 적용이 되지 않습니다

아래의 코드처럼 말이죠

mData.postValue(repository.getAll())
println(data.value)
// 이 코드는 null 을 반환할 수 있습니다

 

 

그렇기 때문에 LiveData 에 즉각적으로 변화를 주고자 한다면 UI 스레드에서 setValue 를 호출하는 것이 좋습니다.. 만

 

상황적인 차이가 있고, DB 에서 가져오는 데이터처럼 양이 굉장히 많다던지 하여

 

UI 스레드를 장시간 차단할 우려가 있는 경우에는 백그라운드에서 postValue 를 사용하여 비동기로 데이터를 세팅한 뒤

 

UI 스레드에서는 작업을 최소화해주시는게 좋습니다.

(빨리 빨리 반영되야한다고 무작정 UI 스레드로 당겨와서 setValue 했다가 ANR(Android Not Respond: 응답없음) 이 발생할 수도 있습니다)

 

어짜피 LiveData 는 Observable 한 객체기 때문에 데이터가 들어오는걸 관측해서 UI 스레드 작업을 하는데 지장이 전혀 없기도 하고요..!