Development record of developer who study hard everyday.

레이블이 안드로이드라이브데이터인 게시물을 표시합니다. 모든 게시물 표시
레이블이 안드로이드라이브데이터인 게시물을 표시합니다. 모든 게시물 표시
, , , ,

안드로이드 LiveData와 switchMap 사용하기

 안드로이드 라이브데이터에 switchMap 사용하기

안드로이드 개발 블로그

회사에서 신규프로젝트를 진행하면서 최대한 리액티브하게 코드를 짜려고 노력했다.

그러다보니 LiveData를 엄청 사용했는데 특정 값이 변하면 함께 변화해줘야하는 값들이 있다.

이럴 경우, 라이브데이터의 Transformations의 map이나 switchMap을 사용하면 편리하다.

나 같은 경우에는 프로젝트에서 지도를 다뤄야했는데 이전 위치와 현재 위치를 통해서 속도를 구해야했다.

LiveData에서 switchMap 사용하기

val currentLocation = MutableLiveData<Location>()
val pastLocation = MutableLiveData<Location>()
val currentVelocity = currentLocation.switchMap {
liveData(Dispatchers.IO) {
currentLocation.value?.let {
// km/s로 구하자
      val beforeLocation = pastLocation.value
Log.d(TAG, "beforeLocation: $beforeLocation")
val afterLocation = currentLocation.value
Log.d(TAG, "afterLocation: $afterLocation")
val distance = beforeLocation?.distanceTo(afterLocation)?.toInt() ?: 0
Log.d(TAG, "distance: $distance")
emit("${(distance * 3.6).toInt()}km")
}

}
}

currentLocation이 현재 위치를 나타내는 라이브데이터.

pastLocation이 이전 위치를 나타내는 라이브데이터이다.

currentVelocity는 currentLocation의 값이 변할 때마다 이전위치와 현재위치를 가지고 속도를 나타내게된다.

속도를 구하는 식 때문에 앱이 느려질까봐 코루틴을 이용하여 계산해주었다.

이때 liveData 코루틴을 사용하려면 build.gradle(앱수준)에

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.0-alpha01"

를 추가해주어야한다.

그리고 값을 내보낼 때는 emit함수를 사용한다.

그럼 currentVelocity에 emit한 값이 입력된다.


여기서 끝내도 좋지만 공부하는 김에 switchMap함수의 원형도 살펴보자.

@MainThread
@NonNull
public static <X, Y> LiveData<Y> switchMap(
@NonNull LiveData<X> source,
@NonNull final Function<X, LiveData<Y>> switchMapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
LiveData<Y> mSource;

@Override
public void onChanged(@Nullable X x) {
LiveData<Y> newLiveData = switchMapFunction.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
result.removeSource(mSource);
}
mSource = newLiveData;
if (mSource != null) {
result.addSource(mSource, new Observer<Y>() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}

복잡해 보이지만 별 거 없다.

source 변수로 라이브데이터를 받아서 source 값이 변할 때마다 switchMapFunction을 호출한다.

switchMapFunction은 라이브데이터를 반환하는 함수인데 switchMapFunction이 반환하는 라이브데이터 newLiveData를 MediatorLiveData 타입의 result 객체에 addSource해준다.

그리고 result 객체를 반환한다.



Share:
Read More