Android에서 RxJava를 사용하는시기와 Android Architectural Components에서 LiveData를 사용하는시기는?


186

Android에서 RxJava를 사용하고 Android Architectural Components에서 LiveData를 사용해야 할 이유를 얻지 못했습니다. 두 가지의 유스 케이스와 차이점이 샘플 예제와 함께 코드 형식으로 설명되어 있으면 둘 다의 차이점을 설명하는 것이 좋습니다.


6
아직 합당한 이유를 찾았습니까? 나는 똑같은 궁금해 ...
IgorGanapolsky

답변:


117

Android LiveData는 활성 / 비활성 전환이 추가 된 원래 옵저버 패턴의 변형입니다. 따라서 범위가 매우 제한적입니다.

Android LiveData에 설명 된 예제를 사용하여 위치 데이터를 모니터링하고 애플리케이션 상태에 따라 등록 및 등록 취소하기위한 클래스가 작성됩니다.

RxJava는 훨씬 일반화 된 연산자를 제공합니다. 이 관측 가능 위치 데이터를 제공한다고 가정 해 봅시다.

Observable<LocationData> locationObservable;

Observable.create()콜백 작업을 매핑 하기 위해 옵저버 블의 구현을 구축 할 수 있습니다 . 옵저버 블이 구독되면 콜백이 등록되고 구독이 취소되면 콜백이 등록 취소됩니다. 구현은 예제에 제공된 코드와 매우 유사합니다.

또한 응용 프로그램이 활성화 될 때 true를 방출하는 Observable이 있다고 가정합니다.

Observable<Boolean> isActive;

그런 다음 다음을 통해 LiveData의 모든 기능을 제공 할 수 있습니다.

Observable<LocationData> liveLocation =
  isActive
    .switchMap( active -> active ? locationObservable : Observable.never() );

switchMap()응용 프로그램이 활성화되어 있지 않으면 운영자 역시 현재의 스트림으로 위치하거나 아무것도 제공한다. 당신은 일단 liveLocation관찰을, 거기에 당신이 RxJava 연산자를 사용하여 함께 할 수있는 많은 것들을. 내가 가장 좋아하는 예는 다음과 같습니다.

liveLocation.distinctUntilChanged()
  .filter( location -> isLocationInAreaOfInterest( location ) )
  .subscribe( location -> doSomethingWithNewLocation( location ) );

위치가 변경된 경우에만 작업을 수행하며 위치가 흥미 롭습니다. 시간 연산자를 결합하여 속도를 결정하는 유사한 작업을 만들 수 있습니다. 더 중요한 것은 RxJava 연산자를 사용하여 기본 스레드에서 작업이 발생하는지 또는 백그라운드 스레드에서 발생하는지 또는 다중 스레드에서 발생하는지에 대한 세부 제어를 제공 할 수 있습니다.

RxJava의 핵심은 라이브러리에서 제공되는 작업 또는 사용자가 제공 한 사용자 지정 작업을 사용하여 제어 및 타이밍을 단일 유니버스로 결합한다는 것입니다.

LiveData는 해당 유니버스의 하나의 작은 부분 만 처리합니다 liveLocation.


2
감사합니다. LiveData 문서는 더 이상 위치 샘플을 참조하지 않는 것 같습니다. (위치 샘플) 더 흥미로운 점은 여기에 있습니다 : androidkt.com/livedata
다니엘 윌슨

5
@DanielWilson 더 이상 링크를 사용할 수 없습니다.
Tura

나는 wtf가 그 링크에 있다는 것을 기억할 수 없다 : 라이브 데이터에 대한 Mark Allison의 샘플 코드와 같은 DI : blog.stylingandroid.com/architecture-components-livedata
Daniel Wilson

3
The point of RxJava is that it combines control and timing into a single universe, using operations provided from the library, or even custom operations that you provide. 그러나 LiveData 수명주기를 인식하지 못합니다. Rx를 사용한다면 수명주기 변경을 처리 할 필요가 없습니까?
Sparker0i

@ Sparker0i 여기에 포인트가 있습니다. RxJava는 라이프 사이클을 인식하지 못합니다. 우리는 수동으로 처리해야합니다. LiveData에서와 같이 이미 수명주기를 처리합니다.
Aks4125

119

원래 질문과 관련하여 RxJava와 LiveData는 서로를 잘 보완합니다.

LiveDataAndroid 라이프 사이클 및과의 긴밀한 통합으로 ViewModel 레이어에서 빛을 발합니다 ViewModel. RxJava@Bob Dalgleish에서 언급 한대로 더 많은 변환 기능을 제공합니다.

현재 우리는 RxJava데이터 소스 및 리포지토리 계층에서 사용하고 있으며 ViewModels에서 데이터를 활동 / 조각에 노출하기 전에 으로 변환 LiveData하여 사용 LiveDataReactiveStreams합니다.이 접근법에 매우 만족합니다.


8
올바르게 이해했다면 LiveData는 Android UI 전용 구현에만 유용합니다. Clean Architecture를 사용하여 일반 앱을 빌드하고이 아키텍처를 다른 플랫폼과 공유하는 경우 RxJava가 LiveData보다 더 적합합니까?
IgorGanapolsky

@IgorGanapolsky 일반 앱에 어떤 언어 / 프레임 워크를 사용하십니까?
kzotin

Java / Kotlin으로 작성된 Android 독립적 API 및 Clean Arch
IgorGanapolsky

1
답변에 LiveDataReactiveStreams의 작동 예를 제안 할 수 있습니까?
Pawan

2
당신이 필요하지 않습니다 @kzotin observeOn, LiveDataReactiveStreams호출하여 어쨌든 않습니다 LiveData.postValue(). 그리고 당신 subscribeOn이 일반적으로 어떤 영향을 미칠 것이라는 보장 은 없습니다 .
arekolek

77

LiveData와 RxJava에는 많은 차이점이 있습니다.

  1. LiveData는 아니다 STREAM RxJava 모든 (문자 그대로 모든)은 인에있는 동안 STREAM .
  2. LiveData는 관찰 가능한 데이터 홀더 클래스입니다. 일반 관측 가능 데이터와 달리 LiveData는 수명주기를 인식하므로 활동, 조각 또는 서비스와 같은 다른 앱 구성 요소의 수명주기를 존중합니다. 이러한 인식은 LiveData가 활성 수명주기 상태 인 앱 구성 요소 관찰자 만 업데이트하도록합니다.
  3. LiveData는 동기식 이므로 RxJava와 마찬가지로 LiveData 만 사용하여 코드 청크 (네트워크 호출, 데이터베이스 조작 등)를 비동기 적으로 실행할 수 없습니다.
  4. 이 듀오를 최대한 활용하기 위해 할 수있는 최선의 방법은 비즈니스 로직 (네트워크 호출, 데이터 조작 등 리포지토리 내외에서 발생하는 모든 작업)에 RxJava를 사용하고 프레젠테이션 계층에 LiveData를 사용하는 것입니다. 이를 통해 비즈니스 로직 및 라이프 사이클 인식 작업을위한 변환 및 스트림 기능을 사용할 수 있습니다.
  5. LiveData와 RxJava 는 함께 사용될 경우 서로 보완 합니다. 내 말은 RxJava로 모든 것을하고 UI를 업데이트하려고 할 때 Observable을 LiveData로 변경하려면 아래 주어진 코드와 같은 것을하십시오. 따라서 View (UI)는 LiveData가 변경 불가능한 MutableLiveData이거나 MutableLiveData가 변경 가능한 LiveData 인 ViewModel의 LiveData를 관찰합니다.
  6. 여기서 질문은 왜 LiveData를 처음부터 사용해야합니까? 아래 코드에서 볼 수 있듯이 RxJava에서 MutableLiveData (또는 LiveData) 로의 응답을 저장하고 LiveData는 수명주기를 인식하므로 데이터는 수명주기를 인식합니다. 이제 데이터 자체가 UI 업데이트시기와시기를 알고있을 때의 가능성을 상상해보십시오.
  7. LiveData에는 기록이 없습니다 (현재 상태 만). 따라서 채팅 응용 프로그램에 LiveData를 사용해서는 안됩니다.
  8. RxJava와 함께 LiveData를 사용하는 경우 MediatorLiveData , SwitchMap 등이 필요하지 않습니다 . 스트림 제어 도구이며 RxJava가 여러 번 향상되어 있습니다.
  9. 데이터 홀더로 LiveData를 참조하십시오. 또한 LiveData는 수명주기 인식 소비자라고 말할 수 있습니다.

    public class RegistrationViewModel extends ViewModel {
        Disposable disposable;

        private RegistrationRepo registrationRepo;
        private MutableLiveData<RegistrationResponse> modelMutableLiveData =
                new MutableLiveData<>();

        public RegistrationViewModel() {
        }

        public RegistrationViewModel(RegistrationRepo registrationRepo) {
            this.registrationRepo = registrationRepo;
        }

        public void init(RegistrationModel registrationModel) {
            disposable = registrationRepo.loginForUser(registrationModel)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Response<RegistrationResponse>>() {
                        @Override
                        public void accept(Response<RegistrationResponse>
                                                   registrationModelResponse) throws Exception {

                            modelMutableLiveData.setValue(registrationModelResponse.body());
                        }
                    });
        }

        public LiveData<RegistrationResponse> getModelLiveData() {
            return modelMutableLiveData;
        }

       @Override
       protected void onCleared() {
                super.onCleared();
            disposable.dispose();
         }
    }

5
데이터 홀더로 LiveData를 참조하십시오. ==> 예
Lou Morda

3
좋은 예입니다. 일회용품을 신고하는 것을 잊어 버렸습니다 onCleared. 를 지우는 것이 좋습니다 .
Snicolas 2016 년

라이브 데이터가 어떻게 동기화되는지 설명해 주시겠습니까? 내가 아는 한 Livedata 객체를 다른 스레드로 보내고 해당 스레드는 관찰자가 MainThread에서들을 수있는 값을 게시 할 수 있습니다.
Hitesh Bisht 2016 년

내가 쓴 것을 다시 읽으면 RxJava를 사용하여 할 수 있듯이 LiveData를 사용하여 다른 스레드에서 작업 할 수 없다는 것을 의미합니다 (예, "어디서나 사용했습니다")
Abhishek Kumar

수명주기는 LiveData의 큰 차별화 요소가 아닙니까? 1. 파이프 라인이 수행해야 할 작업과 최종 결과를 설명하고, 2. "관찰"절의 결과를 구독 한 다음 3. 파이프 라인은 수명주기 상태에서 허용하는 경우에만 작동합니다.
Srg

29

사실, LiveData 에 본질적으로 다른 도구가 아닙니다 RxJava그래서 왜 아키텍처 구성 요소로 도입, RxJava쉽게 수명주기를 관리해야 할 수있는에서 관찰 가능한 모든 구독을 저장하여 CompositeDispoable 그들을 처분 한 후 객체와 onDestroy()Activity 또는 onDestroyView()Fragment 하나를 사용하여 코드 줄?

나는 완전히 RxJava를 사용하여 다음 LiveData를 사용하여 한 번 영화 검색 앱 구축이 질문에 대답 한 여기를 .

그러나 간단히 말해서 그렇습니다.하지만 기본 수명주기 지식을 갖는 것 외에도 관련 수명주기 방법을 우선해야합니다. 이것은 여전히 ​​일부 사람들에게는 의미가 없지만 Google I / O 2018Jetpack 세션 중 하나에 따르면 많은 개발자가 라이프 사이클 관리가 복잡하다는 것을 알았습니다 . 수명주기 종속성을 처리하지 않아 발생하는 충돌 오류는 일부 개발자가 수명주기에 대해 잘 알고 있더라도 앱에서 사용하는 모든 활동 / 조각에서이를 관리하는 것을 잊었 음을 나타내는 또 다른 신호일 수 있습니다. 큰 앱에서는 생산성에 미칠 수있는 부정적인 영향에도 불구하고 문제가 될 수 있습니다.

결론 LiveData은 수명주기 관리, 메모리 누수 및 충돌을 이해하지 않고도 더 많은 수의 개발자가 MVVM을 채택 할 것으로 예상된다는 것입니다. 비록 의심 할 여지없이 기능과 개발자에게 제공하는 기능, 반응 형 프로그래밍과 LiveData비교할 수 없으며 많은 사람들에게 이해하기 어려운 개념과 도구입니다. 다른 한편으로, 나는 많은 개발자들이 겪고있는 논란의 여지가있는 광범위한 문제를 처리하기위한 매우 간단한 도구를 대신 할 수 있다고 생각하지는 않는다 .RxJavaRxJavaLiveDataRxJava

** 업데이트 ** LiveData를 잘못 사용하여 예기치 않은 결과를 초래할 수있는 방법을 설명하는 새 기사를 여기에 추가했습니다 . 이러한 상황에서 RxJava가 구조 될 수 있습니다.



2
"RxJava가 모든 구독을 CompositeDispoable에 저장 한 다음 onDestroy () 활동에 배치하여 라이프 사이클을 쉽게 관리 할 수 ​​있었을 때 도입 된 이유는 무엇입니까?"- 실제로 LiveData폐기 할 것입니다.onStop
arekolek

@arekolek 내 이해 : CompositeDispoable을 처리하기 위해 수명주기 메소드를 덮어 썼습니다. 그러나 라이브 데이터에는 모든 코드가 단일 코드로 포함됩니다. 따라서 최소 20 줄의 코드를 절약하고 있습니다.
Suresh

baseFragment를 정의하고 모든 파생 된 프래그먼트가 재정의 할 Disposable [] subscriptions () 메소드를 정의하고 onCreateView에서이 메소드를 호출하고 CompositeDisposable에 리턴 값을 추가하고 onDestroyView에 더 이상 잊어 버리지 않도록 처리 할 수 ​​있습니다.
android2013

폐기 만하는 것이 아닙니다. RxJava를 사용하면 onStop에 폐기 한 다음 onStart / onResume에서 다시 구독하고 구성 변경을 처리하고 다른 많은 작업을 수행해야합니다. 그렇기 때문에 RxJava를 사용하여 많은 충돌이 발생합니다. LiveData는 모든 것을 처리하지만 RxJava만큼 유연하지는 않습니다.
user932178

24

반응 생태계에서 알 수 있듯이 우리는 데이터를 방출 하는 Observable 과이 Observable 방출을 구독 (알림) 하는 Observer 를 가지고 있으며 , 소위 Observer 패턴이 어떻게 작동하는지 이상한 것은 없습니다. 관찰 가능한 "소리", 관찰자는 주어진 순간에 Observable이 무언가를 외쳤다는 알림을받습니다.

상태 LiveData에있는 옵저버를 관리 할 수있는 옵저버 블이라고 생각하십시오 active. 다른 말로 LiveData하면 간단한 Observable 이지만 수명 주기도 관리합니다.

그러나 요청한 두 가지 코드 사례를 보자.

A) 라이브 데이터

B) RXJava

A) LiveData의 기본 구현입니다

1) 일반적으로 방향 변경을 유지하기 위해 ViewModel에서 LiveData를 인스턴스화합니다 (읽기 전용 인 LiveData 또는 쓰기 가능한 MutableLiveData를 가질 수 있으므로 일반적으로 클래스 LiveData 외부에 노출)

2)에서 OnCreate의 방법은 홈페이지 활동 (안 뷰 모델)을 관찰자 객체를 ( "가입"일반적으로는 A는 onChanged 방법)

3) 메소드를 시작하여 링크를 설정하십시오.

먼저 ViewModel(비즈니스 로직을 소유 함)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

그리고 이것은 MainActivity(가능한 한 바보)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ViewModelProvider= ViewModelProviders.of(this).get(ViewModel::class.java)

        ViewModelProvider.observe(this, Observer {//Points 2 and 3
            //what you want to observe
        })


        }
    }
}

B) 이것이 RXJava의 기본 구현입니다.

1) 당신은 Observable을 선언합니다

2) 당신은 관찰자를 선언

3) Observable을 Observer와 구독

Observable.just(1, 2, 3, 4, 5, 6) // Point 1

   .subscribe(new Subscriber() {    //Points 2 & 3
       @Override
       public void onCompleted() {
           System.out.println("Complete!");
       }

       @Override
       public void onError(Throwable e) {
       }

       @Override
       public void onNext(Double value) {
           System.out.println("onNext: " + value);
       }
    });

특히 아키텍처 구성 요소 와 함께 LiveData사용됩니다 . 실제로 ViewModel과 결합 하면 Observer의 모든 변경 사항을 실시간으로 업데이트 하여 이벤트가 필요한 곳에서 실시간으로 관리 할 수 ​​있습니다. 사용이에 강하게의 개념을 알고하는 것이 좋습니다 라이프 사이클을 상대 개체를 LifeCycleOwner / 라이프 사이클을 , 또한 당신이 한 번 봐 가지고 제안 변환을 구현하려는 경우, 실제 시나리오에서. 여기서 당신은 훌륭한 commonsware 에서 사용 사례를 찾을 수 있습니다 .LifecycleViewModelLiveDataLiveDataLiveData

기본적으로 마무리하는 것은 구성 요소 사이에 명확한 소위 종속성 규칙을 만들지 않고 여러 구성 요소의 변경 사항을 관찰LiveData하는 간단한RXJava방법으로 코드를 훨씬 쉽게 테스트하고 더 읽기 쉽게 만들 수 있습니다. RXJava를 사용하면 LiveData 등을 수행 할 수 있습니다. RXJava의 확장 기능으로 인해 간단한 사례에 LiveData를 사용하거나 Android Architecture 구성 요소를 ViewModel 로 사용하여 RXJava의 모든 기능을 계속 활용할RXJava수 있습니다.물론훨씬 복잡 할 수 있습니다. SwitchMap 및 LiveData의 맵 (현재).

RXJava 버전 2는 객체 지향 패러다임을 혁명적으로 만든 라이브러리로, 프로그램 흐름을 관리하는 기능적 방법을 추가했습니다.


4

LiveData는 Android 팀에서 개발 한 Android 아키텍처 구성 요소의 하위 집합입니다.

라이브 데이터 및 기타 아키텍처 구성 요소를 사용하면 메모리 누수 및 기타 유사한 문제가 아키텍처 구성 요소에 의해 처리됩니다. 그것은 안드로이드 팀에 의해 개발되었으므로 안드로이드에 가장 적합합니다. 또한 새로운 버전의 Android를 처리하는 업데이트도 제공합니다.

Android 앱 개발에만 사용하려면 Android 아키텍처 구성 요소로 이동하십시오. 그렇지 않으면 웹 앱, 데스크탑 앱 등과 같은 다른 Java 앱을 사용하려면 RxJava를 사용하십시오.


귀하의 답변을 명확히하려고 노력했습니다. 어떤 식 으로든 원래 의도와 충돌 한 경우 자유롭게 편집하십시오. 그래도 초기 개정판보다 명확하게 작성하십시오. 답의 마지막 부분은 솔직히 말이되지 않았습니다.
Zoe

2

LiveData데이터 보유자로서 다른 것은 없습니다. 또한 LiveData는 수명주기 인식 소비자라고 할 수 있습니다. LiveData라이프 사이클의 개념과 LifeCycleOwner / LifeCycle의 관련 개체를 알고 있으면 비즈니스 로직 및 라이프 사이클 인식 UI에 대한 변환 및 스트림 기능을 사용할 수 있습니다.

Rx는 우아하고 선언적인 스타일로 문제를 해결할 수있는 강력한 도구입니다. 비즈니스 옵션 또는 서비스 API 작업을 처리합니다.


0

LiveData와 RxJava의 비교는 사과를 과일 샐러드와 비교합니다.

LiveData와 ContentObserver를 비교하면 사과를 사과와 비교합니다. LiveData는 효과적으로 ContentObserver의 수명주기 인식 대체품입니다.

RxJava를 AsyncTask 또는 다른 스레딩 도구와 비교하는 것은 과일 샐러드를 오렌지와 비교하는 것입니다. RxJava는 단순한 스레딩 이상을 지원하기 때문입니다.


0
  • LiveData는 부분적으로 Rx Subject 또는 SharedRxObservable과 같습니다.

  • LiveData는 구독 수명주기를 관리하지만 Rx 주제 구독은 수동으로 작성하고 처리해야합니다.

  • LiveData는 종료 상태는 없지만 Rx Subject에는 OnError 및 OnCompleted가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.