일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 코틀린
- F
- 옵저버 패턴
- designPattern
- 싱글톤
- PrototypePattern
- 디자인패턴 #
- 팩토리 메소드
- Abstract Factory
- ㅓ
- 프로토타입 패턴
- El
- Design Pattern
- 추상 팩토리
- 디자인패턴
- 추상팩토리패턴
- a
- factory method
- Observer Pattern
- r
- builderPattern
- Kotlin
- Singleton
- 빌터패턴
- ㅋㅁ
- Functional Programming
- 함수형프로그래밍
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
LiveData 변환( Transformation class ) 본문
관찰자에게 LiveData 객체를 전달하기 전에 객체에 저장된 값을 변경하고 싶거나 다른 객체의 값에 따라 다른 LiveData인스턴스를 반환해야 하는 경우가 있습니다.
즉, 변경된 LiveData를 observer에게 전달하기 전에 데이터를 가공하고 싶거나, 다른 LiveData를 만들고 싶다면 Transformations을 이용합니다.
앱의 모든 계층에서 LiveData를 사용하는 일반적인 흐름도
LiveData 객체에 저장된 값에 함수를 적용하고 결과를 다운스트림으로 전파합니다.
View가 DESTROY 된 경우, View의 수명주기가 연속된 관찰자(Observers)로 다운 스트림으로 전파되므로
이러한 subscriptions을 해체할 필요가 없습니다.
구성 요소 간에 데이터를 전달하려면 매핑 및 결합 방법이 필요하다.
MediatorLiveData는 Transformations 클래스의 도우미와 함께 매핑 및 결합을 위해 사용됩니다.
Transformations.map
public static LiveData <Y> map (LiveData <X> source, Function <X, Y> mapFunction)
- Transformations.map의 핵심은
source(LiveData)의 값을 mapFunction을 통해 새로운 값을 생성 후 그것을 LiveData로 넘겨준다.
- mapFunction은 LiveData가 아닌 값을 반환한다.
- LiveData를 return 하며, source에 이벤트가 생길 때마다 main thread에서 function이 수행된다.
- userLiveData를 가지고 아래처럼 userFullNameLiveData를 생성한다.
UserLiveData의 변경사항을 Observe 해서 함수를 통해 원하는 값으로 변경한 뒤 ‘String’을 리턴합니다. 즉 새로운 LiveData를 리턴하는 게 아닌 데이터만 변경합니다.
LiveData<User> userLiveData = ...;
LiveData<String> userFullNameLiveData =
Transformations.map(
userLiveData,
user -> user.firstName + user.lastName);
});
Transformations.switchMap()
public static LiveData <Y> switchMap (LiveData <X> source, Function <X, LiveData <Y>> switchMapFunction)
- map과 유사하게 LiveData 객체에 저장된 값에 함수를 적용하고 결과를 다운 스트림으로 풀고 디스 패치합니다. switchMap()에 전달된 함수는 LiveData 객체를 반환해야 합니다
- SwitchMap은 LiveData를 변경사항을 받아서 다른 LiveData를 발행합니다. 일반적으로 RoomDatabase를 LiveData로 쓸 때 많이 사용합니다.
- switchMapFunction은 메인 스레드에서 실행된다.
- switchMap()을 사용하여 관찰자의 수명 주기 전반에 걸쳐 정보를 전달할 수 있습니다.
관찰자가 반환된 LiveData 객체를 관찰하고 있지 않다면 변환은 계산되지 않습니다.
변환은 lazy 계산되기 때문에 수명 주기 관련 동작은 추가적인 명시적 호출이나 종속성 없이도 암시적으로 전달됩니다.
- switchMap은 내부적으로 MediatorLiveData를 사용하므로 LiveData의 여러 소스를 결합할 때 사용해 야하므로 중요하다.
예시)
UI 구성요소는 getPostalCode()를 호출할 때마다 이전 LiveData 객체에서 등록을 취소하고 새 인스턴스에 등록해야 합니다. 또한 UI 구성요소가 다시 생성되면 이전 호출의 결과를 사용하지 않고 또 다른 repository.getPostCode() 메서드 호출을 트리거합니다.
class MyViewModel extends ViewModel {
private final PostalCodeRepository repository;
public MyViewModel(PostalCodeRepository repository) {
this.repository = repository;
}
private LiveData<String> getPostalCode(String address) {
// DON'T DO THIS
return repository.getPostCode(address);
}
}
아래의 경우 postalCode 필드는 addressInput의 변환으로 정의됩니다.
앱에 postalCode 필드와 연결된 활성 상태의 관찰자가 있는 한 addressInput이 변경될 때마다 필드 값은 다시 계산되고 회수됩니다. 이 메커니즘을 사용하면 앱의 하위 수준(RoomDB 등)에서 요청이 있을 때 lazy 계산되는 LiveData 객체를 생성할 수 있습니다. ViewModel 객체는 LiveData 객체의 참조를 쉽게 가져와서 그 위에 변환 규칙을 정의할 수 있습니다.
class MyViewModel extends ViewModel {
private final PostalCodeRepository repository;
private final MutableLiveData<String> addressInput = new MutableLiveData();
public final LiveData<String> postalCode =
Transformations.switchMap(addressInput, (address) -> {
return repository.getPostCode(address);
});
public MyViewModel(PostalCodeRepository repository) {
this.repository = repository
}
private void setInput(String address) {
addressInput.setValue(address);
}
}
'Android Jetpack Architecture > LiveData' 카테고리의 다른 글
DataBinding과 LiveData (0) | 2020.08.18 |
---|---|
LiveData( MediatorLiveData ) (0) | 2020.08.18 |
LiveData 사용 하기 (0) | 2020.08.15 |
LiveData 개요와 이점 (0) | 2020.08.15 |