코딩을 하던 도중 Test Code를 짯고 LiveData를 이용해서 데이터 Update를 시켜주는 작업을 하고 있었다.
하지만, 리스트를 가져오는 두개의 함수에서 하나의 결과만 Update가 되었다.
1) Observer가 Active하지 않은 경우
Observer 클래스로 표현되는 관찰자의 수명 주기가 STARTED 또는 RESUMED 상태이면 LiveData는 관찰자를 활성 상태로 간주합니다. LiveData는 활성 관찰자에게만 업데이트 정보를 알립니다. LiveData 객체를 보기 위해 등록된 비활성 관찰자는 변경사항에 관한 알림을 받지 않습니다.
'활성 상태'가 아닌 observer는 LiveData의 값 변경을 인식할 수 없다는 것이다.
활동이나 프래그먼트에 활성 상태가 되는 즉시 표시할 수 있는 데이터가 포함되도록 하기 위함입니다. 앱 구성요소는 STARTED 상태가 되는 즉시 관찰하고 있던 LiveData 객체에서 최신 값을 수신합니다. 이는 관찰할 LiveData 객체가 설정된 경우에만 발생합니다.
이 말인 즉슨, observer가 활성 상태(위 경우에는 STARTED)가 되는 순간, '마지막으로 변경된 값'만을 라이브데이터에서 수신한다는 뜻이 되겠다.
출처의 예제에서
onCreate에서 연속적으로 livedata.value로 값을 변경하였고, onResume에서도 값을 변경하여 비교하였다.
onCreate에서는 마지막 값만 호출되었다.
이유는 간단하다. 메소드가 마지막 숫자인 4를 셀 때까지 아직 STARTED(활성) 상태에 도달하지 못했기 때문이다.
그리고 나서 화면이 STARTED상태에 돌입한 후, '가장 마지막으로 변경된 값'인 4를 받아 출력한 것이다.
onResume에서는 전부 변경값이 호출 되었다.
이 경우에는 observer가 항상 ACTIVE한 상태이므로,
기대한 것과 같이 모든 값이 출력되는 것을 볼 수 있었다.
따라서 모종의 이유로 observer가 여러 값을 연속적으로 받아서 동작해야만 하는 경우에는 우선 onCreate에서 observer등록을 해 준 후에,
a) 값 변경이 onStart 이후에 이루어지도록 명시하거나
b) 화면이 활성 상태일 때 사용자의 입력을 통해 변경되도록 하는 것이 좋겠다.
2) postValue에서의 데이터 누락
setValue, postValue
두 방식의 가장 큰 차이점은 스레드이다.
postValue로 값을 설정할 경우 백그라운드에서 값이 변경되고 동기적으로 observe되지만,
setValue의 경우에는 UI 스레드에서 직접 값을 변경한다.
두 메소드를 보면, setValue()의 경우에는 단순히 mData를 주어진 값으로 변경하는 작업을 수행하지만,
postValue()의 경우 synchronized가 걸려 있어 여러 작업이 동시에 수행되지 못한다.
멀티스레드 작업에서 동작 순서가 보장되지 않는 만큼, 값이 동시에 변하는 것을 막기 위함으로 보인다.
요약
- observer가 ACTIVE하지 않은 상태(onCreate)에서 들어온 값들은 가장 마지막 값만이 observer에 전달되고,
- postValue()를 사용한 업데이트는 너무 빈번하게 호출되면 누락될 수 있다.
출처 :
'안드로이드' 카테고리의 다른 글
Android Adb(Android Debug Bridge) Path 설정(MAC) (0) | 2022.03.28 |
---|---|
Android WebView (React 서비스 화면과 통신) (0) | 2022.03.21 |
RecyclerView 데이터바인딩 + ItemTouchHelper시 데이터 중복문제 (0) | 2022.02.23 |
setOnclick, clickable의 관계 (0) | 2021.11.08 |
탭레이아웃 탭 개수가 한개일 경우 (0) | 2021.11.03 |