Когда использовать RxJava в Android и когда использовать LiveData от Android Architectural Components?

Я не получаю причины использовать RxJava в Android и LiveData от архитектурных компонентов Android. Было бы очень полезно, если бы объяснения и различия между ними объяснялись вместе с примером примера в виде кода, который объясняет различия между ними.

Ответ 1

Android LiveData - это вариант исходного шаблона наблюдателя с добавлением активных/неактивных переходов. Таким образом, он очень ограничительный по своему охвату.

Используя пример, описанный в Android LiveData, создается класс для контроля данных местоположения и регистрации и отмены регистрации на основе состояния приложения.

RxJava предоставляет операторы, которые гораздо более обобщены. Предположим, что это наблюдение предоставит данные о местоположении:

Observable<LocationData> locationObservable;

Реализация наблюдаемого может быть построена с использованием Observable.create() для сопоставления операций обратного вызова. Когда наблюдаемый подписывается, обратный вызов регистрируется, и когда он не подписывается, обратный вызов не регистрируется. Реализация выглядит очень похоже на код, представленный в примере.

Предположим также, что у вас есть наблюдаемое, которое испускает true, когда приложение активно:

Observable<Boolean> isActive;

Затем вы можете предоставить всю функциональность LiveData следующим

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

Оператор switchMap() будет либо предоставлять текущее местоположение как поток, либо ничего, если приложение неактивно. После того, как у вас будет liveLocation значение liveLocation, с ним можно многое сделать, используя операторы RxJava. Мой любимый пример:

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

Это действие будет выполняться только при изменении местоположения, и место будет интересным. Вы можете создавать аналогичные операции, которые объединяют операторы времени для определения скорости. Что еще более важно, вы можете предоставить подробный контроль того, происходят ли операции в основном потоке, или в фоновом потоке, или в нескольких потоках, с использованием операторов RxJava.

Точка RxJava заключается в том, что она сочетает управление и синхронизацию в единый юниверс, используя операции, предоставляемые из библиотеки, или даже настраиваемые операции, которые вы предоставляете.

LiveData адресует только одну небольшую часть этого юниверса, что эквивалентно построению liveLocation.

Ответ 2

Что касается исходного вопроса, то и RxJava, и LiveData прекрасно дополняют друг друга.

LiveData светит на уровне ViewModel, с его тесной интеграцией с жизненными LiveData Android и ViewModel. RxJava предоставляет больше возможностей в преобразованиях (как упоминает @Bob Dalgleish).

В настоящее время мы используем RxJava в слоях источника данных и репозитория, и он преобразуется в LiveData (используя LiveDataReactiveStreams) в ViewModels (до LiveDataReactiveStreams данных в действия/фрагменты) - вполне доволен этим подходом.

Ответ 3

Между LiveData и RxJava много различий:

  1. LiveData не является STREAM, тогда как в RxJava все (буквально все) является STREAM.
  2. LiveData - это наблюдаемый класс держателя данных. В отличие от обычной наблюдаемой, LiveData учитывает жизненный цикл, то есть он учитывает жизненный цикл других компонентов приложения, таких как действия, фрагменты или службы. Эта осведомленность гарантирует, что LiveData обновляет только те компоненты приложения, которые находятся в состоянии активного жизненного цикла.
  3. LiveData является синхронным, поэтому вы не можете асинхронно выполнять фрагмент кода (сетевой вызов, манипулирование базой данных и т.д.), Используя только LiveData, как и в RxJava.
  4. Лучшее, что вы можете сделать, чтобы использовать большую часть этого дуэта, это использовать RxJava для вашей бизнес-логики (сетевой вызов, манипулирование данными и т.д., Все, что происходит в репозитории и за его пределами) и использовать LiveData для уровня презентации. Таким образом, вы получаете возможности преобразования и потоковой передачи для своей бизнес-логики и операции с учетом жизненного цикла для вашего пользовательского интерфейса.
  5. LiveData и RxJava дополняют друг друга, если используются вместе. Я имею в виду, что все делайте с RxJava, а в конце, когда вы захотите обновить пользовательский интерфейс, сделайте что-то вроде приведенного ниже кода, чтобы изменить Observable на LiveData. Итак, ваш View (UI) наблюдает за LiveData в ViewModel, где ваши LiveData - это не что иное, как неизменяемый MutableLiveData (или MutableLiveData является изменяемым LiveData).
  6. Итак, вопрос в том, зачем вам вообще использовать LiveData? Как вы можете видеть ниже в коде, вы сохраняете свой ответ из RxJava в MutableLiveData (или LiveData), а ваши LiveData учитывают жизненный цикл, поэтому в некотором смысле ваши данные учитывают жизненный цикл. А теперь представьте себе возможность, когда ваши данные будут знать, когда и когда не обновлять пользовательский интерфейс.
  7. LiveData не имеет истории (только текущее состояние). Следовательно, вы не должны использовать LiveData для приложения чата.
  8. Когда вы используете LiveData с RxJava, вам не нужны такие вещи, как 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();
         }
    }

Ответ 4

Фактически, LiveData не является принципиально отличным инструментом от RxJava, поэтому почему он был представлен как компонент архитектуры, когда RxJava мог легко управлять жизненным циклом, сохраняя все подписки на наблюдаемые в объекте CompositeDispoable а затем onDestroy() их в onDestroy() Activity или onDestroyView() Fragment использующего только одну строку кода?

Я ответил на этот вопрос в полной мере путем создания поискового приложения фильм один раз RxJava, а затем с помощью LiveData здесь.

Короче говоря, да, это возможно, но для этого нужно сначала переопределить соответствующие методы жизненного цикла, помимо базовых знаний жизненного цикла. Это все еще может не иметь смысла для некоторых, но дело в том, что согласно одному из сеансов Jetpack в Google I/O 2018 многие разработчики находят сложным управление жизненным циклом. Ошибки сбоя, возникающие из-за отсутствия обработки зависимости от жизненного цикла, могут быть еще одним признаком того, что некоторые разработчики, даже не зная жизненного цикла, забывают заботиться об этом в каждой операции/фрагменте, который они используют в своем приложении. В больших приложениях это может стать проблемой, несмотря на негативное влияние, которое это может оказать на производительность.

Суть в том, что благодаря внедрению LiveData большее число разработчиков, как ожидается, примут MVVM, даже не разбираясь в управлении жизненным циклом, утечке памяти и сбоях. Несмотря на то, что я не сомневаюсь, что LiveData несопоставим с RxJava с точки зрения возможностей и мощности, которую он дает разработчикам, реактивное программирование и RxJava - это сложная для понимания концепция и инструмент для многих. С другой стороны, я не думаю, что LiveData предназначается, чтобы быть замена для RxJava -эта просто не могу, но очень простой инструмент для обработки спорного вопроса широко распространенное испытываемого многими разработчиками.

** ОБНОВЛЕНИЕ ** Я добавил новую статью здесь, где я объяснил, как неправильное использование LiveData может привести к неожиданным результатам. RxJava может прийти на помощь в этих ситуациях


Ответ 5

Как вы, возможно, знаете, в реактивной экосистеме у нас есть Observable, который испускает данные, и Observer, который подписывается (получает уведомление) об этом Observable излучении, нет ничего странного в том, как работает так называемый паттерн Observer. Наблюдаемый что-то "кричит", Наблюдатель получает уведомление, что Наблюдаемый что-то кричит в данный момент.

Думайте о LiveData как о Наблюдаемой, которая позволяет вам управлять Наблюдателями, которые находятся в active состоянии. Другими словами, LiveData является простой Observable, но также заботится о жизненном цикле.

Но давайте рассмотрим два кода, которые вы запрашиваете:

А) Живые данные

Б) RXJava

А) Это базовая реализация LiveData

1) вы обычно создаете экземпляр LiveData в ViewModel для поддержания изменения ориентации (у вас могут быть LiveData, предназначенные только для чтения, или MutableLiveData, доступные для записи, поэтому вы обычно выставляете их вне класса LiveData)

2) в методе OnCreate основного действия (не ViewModel) вы "подписываете" объект Observer (обычно это метод 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
        })


        }
    }
}

Б) Это базовая реализация RXJava

1) вы объявляете наблюдаемую

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 используется с Lifecycle и часто с компонентами архитектуры ViewModel (как мы уже видели). Фактически, когда LiveData объединяется с ViewModel, вы можете обновлять в реальном времени каждое изменение в Observer, так что события управляются в реальном времени там, где это необходимо. Для использования LiveData настоятельно рекомендуется знать концепцию жизненного цикла и относительных объектов LifeCycleOwner/LifeCycle, также я бы посоветовал вам взглянуть на Transformations, если вы хотите реализовать LiveData в реальных сценариях жизни. Здесь вы можете найти несколько вариантов использования от большого общего программного обеспечения.

По сути, LiveData - это упрощенный RXJava, элегантный способ наблюдать за изменениями в нескольких компонентах без создания явных так называемых правил зависимости между компонентами, чтобы вы могли намного проще протестировать код и сделать его намного более читабельным. RXJava, позволяет вам делать вещи LiveData и многое другое. Из-за расширенных функциональных возможностей RXJava вы можете использовать LiveData для простых случаев или использовать всю мощь RXJava, продолжая использовать компоненты архитектуры Android в качестве ViewModel, конечно, это означает, что RXJava может быть гораздо более сложным, просто представьте, что у него сотни операторов вместо SwitchMap и Map LiveData (на данный момент).

RXJava версии 2 - это библиотека, которая произвела революцию в объектно-ориентированной парадигме, добавив так называемый функциональный способ управления потоком программы.

Ответ 6

LiveData - это подмножество компонентов архитектуры Android, разработанных командой Android.

С текущими данными и другими компонентами архитектуры утечки памяти и другие подобные проблемы решаются компонентами архитектуры. Так как он разработан командой Android, он является лучшим для Android. Они также предоставляют обновления для новых версий Android.

Если вы хотите использовать только при разработке приложений для Android, выберите компоненты архитектуры Android. В противном случае, если вы хотите использовать другое приложение Java, такое как веб-приложение, настольные приложения и т.д., Используйте RxJava

Ответ 7

LiveData как вещь держателя данных и ничего больше. Можно также сказать, что LiveData - потребитель, осведомленный о жизненном цикле. LiveData настоятельно рекомендуется знать концепцию жизненного цикла и относительных объектов LifeCycleOwner/LifeCycle, вы получаете возможности преобразования и потоковой передачи для своей бизнес-логики и операции с учетом жизненного цикла для вашего пользовательского интерфейса.

Rx - это мощный инструмент, который позволяет решить проблему в элегантном декларативном стиле. Он обрабатывает бизнес-параметры или операции Service Api