Lifecycle 2.7.0-alpha02에서 LiveData 관련 동작이 변경되었다.
The
LiveData.map()
andLiveData.switchMap()
extensions now sets thevalue
of the returnedLiveData
if the previousLiveData
has had a value set on it, ensuring that using the resulting LiveData in Jetpack Compose has the right state on the initial composition. (I91d2b, b/269479952)
Compose 관련 변경으로 보이지만, LiveData map/switchMap extension의 동작 변경이다.
Source에 해당하는 LiveData 값이 존재하는 경우, 즉시 값 처리를 한다는 의미이다.
테스트할 샘플 코드는 Source LiveData(trigger)에 값을 미리 설정한 후 LiveData#map 처리를 하도록 작성했다.
특이한 부분은 trigger 시점과 실제 값을 사용할 LiveData가 개별로 정의되어 있다.
class MainViewModel : ViewModel() {
// Source LiveData
private val trigger: MutableLiveData<Int> = MutableLiveData(8)
val b = trigger.map {
if ((_a.value ?: 0) > 0) it
else 0
}
// Real Value LiveData
private val _a = MutableLiveData<Int>()
}
class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModel.b.observe(this) {
Log.d("Pluu", "Received=${it}")
}
}
}
Issue Tracker에 제보한 이슈 : https://issuetracker.google.com/issues/332328882
구글 직원의 답변에 의하면 LiveData map/switchMap extensions이 distinctUntilChanged 동작을 적용했다고 한다. 즉, Source LiveData에 값이 이미 채워져 있다면 map/switchMap의 transform block이 즉시 실행되도록 변경되었다고 한다.
2.7.0-alpha02부터 발생한 이슈의 해결법은 단순하다.
_a의 선언을 b보다 먼저 선언하면 된다.
class MainViewModel : ViewModel() {
// Source LiveData
private val trigger: MutableLiveData<Int> = MutableLiveData(8)
// Real Value LiveData
private val _a = MutableLiveData<Int>() // Fixed 2.7.0-alpha02
val b = trigger.map {
if ((_a.value ?: 0) > 0) it
else 0
}
}
comments powered by Disqus
Subscribe to this blog via RSS.