[Android/Kotlin] Transformations.map() vs switchMap()

hyomin·2022년 4월 17일
0

Android

목록 보기
8/9

1. 리턴 타입

LiveData map (LiveData source, Function<X, Y> func): LiveData 타입 데이터를 LiveData 타입 데이터로 변환합니다. func에서는 Y 타입의 객체를 리턴.

val userLiveData : LiveData<User> = MutableLiveData(User("Jone", "Doe"))
val userName : LiveData<String> = Transformations.map(userLiveData) { user ->
    user.firstName + user.lastName        
} 

LiveData switchMap (LiveData trigger, Function<X, LiveData> func): LiveData 타입 데이터를 LiveData 타입 데이터로 변환합니다. func에서는 LiveData 타입의 객체를 리턴.

  
val userLiveData : LiveData<User> = MutableLiveData(User("Jone", "Doe"))
val userName : LiveData<String> = Transformations.switchMap(userLiveData) { user ->
    MutableLiveData(user.firstName + user.lastName)
}

2. 정적 변환 vs 동적 변환

map() : 정적 변환


데이터 변화가 있을 때 즉각적으로 변환만 하면 되는 경우, 아래 코드처럼 map()을 사용할 수 있습니다. LiveData인 Source의 변경이 발생하면 데이터가 변환되어 viewModelResult(LiveData)를 수신하는 Observer에게 이벤트가 전달됩니다.

class MainViewModel {
  val viewModelResult = Transformations.map(repository.getDataForUser() { data ->
     convertDataToMainUIModel(data)
  }
}  

switchMap() : 동적변환


즉각적으로 데이터 변환이 어려워 초기화 구간에 사용할 수는 없지만, 가까운 미래에 사용해도 된다면 switchMap()으로 구현할 수 있습니다.

switchMap()은 LiveData 객체를 리턴하기 때문에 repository.getDataForUser(user)에서 미래에 사용할 LiveData를 리턴하고, 준비가 끝났을 때 repository.getDataForUser(user) 내부에서 변환된 데이터를 이전에 리턴한 LiveData에 업데이트할 수 있습니다.

class MainViewModel {
  val repositoryResult = Transformations.switchMap(userManager.user) { user ->
     repository.getDataForUser(user)
  }
}  

3. 단순한 작업 vs 오래 걸리는 작업

map()과 switchMap()이 Main Thread에서 동작할 때, 작업이 오래 걸리면 UI가 일정 시간 멈추거나 ANR이 발생할 수 있습니다.
switchMap()은 먼저 LiveData 객체를 리턴하고, 다른 쓰레드에서 오래 걸리는 작업을 수행하고 완료되면 LiveData로 업데이트하도록 구현하였습니다. switchMap()을 호출하는 쓰레드는 바로 LiveData 객체를 받기 때문에 쓰레드가 Block되는 일은 없습니다. 다만, 다른 쓰레드에서 처리가 완료되어야 LiveData에 데이터가 업데이트됩니다.

출처
https://codechacha.com/ko/android-jetpack-difference-map-and-switchmap/

profile
🌱

0개의 댓글