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

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

11 ответов

Решение

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

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

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

Observable<LocationData> locationObservable;

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

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

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,

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

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

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

Есть много различий между LiveData и RxJava

  1. LiveData не является STREAM, в то время как в Rxjava все (буквально все) является STREAM.
  2. LiveData является синхронным, поэтому вы не можете асинхронно выполнять фрагмент кода (вызов nework, манипулирование базой данных), используя только LiveData, как это делается в Rxjava.
  3. Лучшее, что вы можете сделать, чтобы использовать большую часть этого дуэта, это использовать Rxjava для вашей бизнес-логики (сетевой вызов, манипулирование данными и т. Д., Все, что происходит в репозитории и за его пределами) и использовать LiveData для уровня презентации. Таким образом, вы получаете возможности преобразования и потоковой передачи для своей бизнес-логики и работы с учетом жизненного цикла для вашего пользовательского интерфейса.
  4. LiveData и Rxjava дополняют друг друга, если используются вместе. Я имею в виду, что все делайте с RxJava, а в конце, когда вы захотите обновить пользовательский интерфейс, сделайте что-то вроде приведенного ниже кода, чтобы превратить ваш Observable в Livedata. Итак, ваш View(UI) наблюдает за Livedata в ViewModel, где ваши LiveData - это не что иное, как не изменяемый MutableLiveData (или MutableLiveData является изменяемым LiveData).
  5. Итак, вопрос в том, почему вы вообще должны использовать LiveData? Как вы можете видеть ниже в коде, вы сохраняете свой ответ из Rxjava в MutableLiveData (или LiveData), а ваши LiveData ориентированы на жизненный цикл, так что в некотором смысле ваши данные учитывают жизненный цикл. Теперь представьте себе возможность, когда ваши данные будут знать, когда и когда не обновлять пользовательский интерфейс.

  6. LiveData не имеет истории (только текущее состояние). Следовательно, вы не должны использовать LiveData для приложения чата.

  7. Когда вы используете LiveData с RxJava, вам не нужны такие вещи, как MediatorLiveData, SwitchMap и т. Д. Они являются инструментами управления потоками, и RxJava во многих случаях лучше.
  8. Посмотрите LiveData как вещь держателя данных и ничего больше. Можно также сказать, что LiveData - потребитель, осведомленный о жизненном цикле.

     public class RegistrationViewModel extends ViewModel {
    
        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;
             }
    }
    

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

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

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

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

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


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

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

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

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

Б) RXJava

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

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

2) в OnCreate метод Main Activity (не 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, также я бы посоветовал вам взглянуть на Преобразования, если вы хотите реализовать LiveData в реальных сценариях. Здесь вы можете найти несколько вариантов использования от общей одежды.

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

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

LiveData - это подмножество компонентов архитектуры android, разработанных командой android. С живыми данными и другими компонентами архитектуры (лучше всего подходит для android. Утечки памяти и т. Д. Обрабатываются компонентами архитектуры. Так как они разработаны командой android. Так что это лучше всего подходит для Android, они предоставляют обновления с учетом новых версий Android и т. Д.) Мы можем сделать то, что мы можем достичь в RxJava.
Если вы хотите использовать в Android только средства, перейдите к компонентам архитектуры Android, и если вы хотите использовать модуль ur в Android и других средствах (Java-приложение и т. Д.), Перейдите к RxJava (реагирует нативно)

  • LiveData частично совпадает с Rx Subject или SharedRxObservable

  • LiveData управляет жизненным циклом подписки, но подписку Rx Subject следует создавать и удалять вручную.

  • LiveData не имеет состояния завершения, но у Rx Subject есть OnError и OnCompleted

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

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

Сравнение LiveData с RxJava - это сравнение яблок с фруктовыми салатами.

Сравните LiveData с ContentObserver, и вы сравниваете яблоки с яблоками. LiveData эффективно заменяет ContentObserver с учетом жизненного цикла.

Сравнение RxJava с AsyncTask или любым другим инструментом потоковой передачи - это сравнение фруктовых салатов с апельсинами, потому что RxJava помогает не только в потоковой передаче.

Мой простой ответ: не используйте RxJava. Это слишком сложно и злоупотребляется. Все проекты, использующие RxJava, трудно поддерживать и отлаживать. RxJava делает что-то асинхронно, используя потоки внутри него для отправки запросов, в общем случае это совершенно не нужно, и если это необходимо, сопрограмма Kotlin справится лучше, возможно, в 99% случаев.

LiveData и RxJava — это библиотеки реактивного программирования, которые можно использовать для обработки данных в приложениях Android. Они оба существуют уже некоторое время и имеют свои сильные и слабые стороны.

LiveData

Плюсы: Простота в использовании. С учетом жизненного цикла, поэтому обновляются только те наблюдатели, которые находятся в активном состоянии жизненного цикла. Хорошо интегрирован с библиотеками Android Jetpack. Минусы: Не такой мощный, как RxJava. Может использоваться только для наблюдения за изменениями данных.RxJava

Плюсы: Очень мощный. Может использоваться для обработки широкого спектра задач с данными, таких как сетевые вызовы, операции с базами данных и обновления пользовательского интерфейса. Имеет большое сообщество разработчиков и библиотек. Минусы: сложнее в освоении и использовании, чем LiveData. Не учитывает жизненный цикл, поэтому вам придется управлять подписками вручную. Пример

Вот пример того, как использовать LiveData для наблюдения за изменением данных:

класс MyActivity : AppCompatActivity() {

      private val liveData = MutableLiveData<String>()

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

    // Observe the LiveData and update the UI when the data changes.
    liveData.observe(this, { newData ->
        textView.text = newData
    })

    // Set the initial data.
    liveData.value = "Hello, world!"
}

} Вот пример использования RxJava для наблюдения за изменением данных:

класс MyActivity : AppCompatActivity() {

      private val observable = Observable.create<String> { emitter ->
    emitter.onNext("Hello, world!")
}

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

    // Observe the Observable and update the UI when the data changes.
    observable.subscribe { newData ->
        textView.text = newData
    }
}

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

Какой из них вам следует использовать?

Выбор лучшей библиотеки зависит от ваших конкретных потребностей. Если вам нужен простой способ наблюдать за изменениями данных и обновлять пользовательский интерфейс, LiveData — хороший выбор. Если вам нужно больше мощности и гибкости, то RxJava — хороший вариант. Однако, если вы новичок в реактивном программировании, лучше начать с LiveData.

Другие вопросы по тегам