Коли використовувати RxJava в Android та коли використовувати LiveData від Android Architectural Components?


186

Я не отримую приводу використовувати RxJava в Android та LiveData від Android Architectural Components. Це було б дуже корисно, якщо користувальницькі випадки та відмінності між обома пояснюються разом із прикладом зразка у вигляді коду, який пояснює відмінності між обома.


6
Ви знайшли ще вагому причину? Мені цікаво те саме ...
ІгорГанапольський

Відповіді:


117

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.


2
Дякую, документи LiveData, схоже, більше не посилаються на зразок місцеположення. Тут є ще цікаві моменти (із зразком місцеположення): androidkt.com/livedata
Daniel Wilson

5
@DanielWilson посилання більше недоступне.
Тура

Чувак, я не можу пригадати, щоб Wtf був на цьому посиланні: 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 дуже добре доповнюють один одного.

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

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


8
Якщо ми вас зрозуміли правильно, LiveData корисна лише для реалізованих інтерфейсів Android. Якщо ми просто створюємо загальний додаток із Clean Architecture і ділимось цією архітектурою з іншими платформами, то RxJava - це краще, ніж LiveData?
ІгорГанапольський

@IgorGanapolsky якою мовою / рамками ви користуєтесь для загальної програми?
kzotin

Незалежні від Android API та Clean Arch написані на Java / Kotlin.
ІгорГанапольський

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 синхронний , тому ви не можете виконати шматок коду (мережевий дзвінок, маніпуляція базою даних тощо) асинхронно, використовуючи лише LiveData, як це робиться з RxJava.
  4. Найкраще, що ви можете зробити, щоб максимально використати цей дует, - це використовувати RxJava для вашої бізнес-логіки (мережевий дзвінок, маніпулювання даними тощо, все, що відбувається в репозиторії та поза ним ) та використовувати LiveData для вашого презентаційного шару. Цим ви отримуєте можливості перетворення та передачі потоку для вашої бізнес-логіки та життєздатного циклу роботи вашого інтерфейсу.
  5. LiveData та RxJava компліментують один одному, якщо вони використовуються разом. Що я маю на увазі - зробіть все з RxJava, і в кінці, коли ви хочете оновити інтерфейс користувача, зробіть щось на зразок коду, наведеного нижче, щоб змінити свою спостережувану в LiveData. Отже, ваш Перегляд (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();
         }
    }

5
Дивіться LiveData як річ із власником даних і нічого іншого. ==> ТАК
Лу Морда

3
Гарний приклад. Ви забули декларувати одноразові, і було б непогано їх видалити onCleared.
Snicolas

Чи можете ви поясніть, наскільки живі дані синхронізовані? Наскільки я знаю, ми можемо переслати об’єкт Livedata в інший потік, і тоді цей потік може поступити значення, який спостерігач може слухати в MainThread.
Hitesh Bisht

Якщо ви знову прочитаєте те, що я написав, це означає, що ви не можете працювати тільки над іншою темою (Так, я використовував "просто" навіть там), використовуючи LiveData, як це можна зробити, використовуючи RxJava
Abhishek Kumar

Чи не життєвий цикл є великим диференціатором для LiveData? Ви 1. описуєте, що потрібно робити вашому трубопроводу та які ваші кінцеві результати, 2. підписуєтесь на результат у пунктах "дотримуйтесь", а потім 3. трубопровід експлуатується лише у тому випадку, якщо це дозволяє ваш стан життєвого циклу.
Серг

29

Насправді, LiveData це не суттєво відрізняється інструментом RxJava, так чому він був введений в якості компонента архітектури , коли RxJavaможна було б легко управляти життєвим циклом, зберігаючи всі підписки на спостережуваних в CompositeDispoable об'єкті , а потім утилізації їх в onDestroy() з Activity або onDestroyView() з , Fragment використовуючи тільки один рядок коду?

Я повністю відповів на це питання, створивши додаток для пошуку фільмів один раз, використовуючи RxJava, а потім використовуючи LiveData тут .

Але коротше, так, це могло б, але для цього знадобиться спочатку переосмислити відповідні методи життєвого циклу, крім того, щоб мати базові знання про життєвий цикл. Це все ще може не мати сенсу для деяких, але факт полягає в тому, що згідно з одним із сесій Jetpack в Google I / O 2018, багато розробників знаходять комплекс управління життєвим циклом. Помилки аварійних ситуацій, що виникають внаслідок невідповідності залежності життєвого циклу, можуть бути ще однією ознакою того, що деякі розробники, навіть якщо знають життєвий цикл, забувають подбати про це у кожній діяльності / фрагменті, яку вони використовують у своєму додатку. У великих програмах це може стати проблемою, незважаючи на негативний вплив, який він може мати на продуктивність.

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

** ОНОВЛЕННЯ ** Додав сюди нову статтю, де я пояснив, як неправильне використання LiveData може призвести до несподіваних результатів. RxJava може прийти на допомогу в цих ситуаціях



2
"чому це було запроваджено, коли RxJava міг легко керувати життєвим циклом, зберігаючи всі підписки в CompositeDispoable, а потім розміщуючи їх у OnDestroy () Діяльності" - LiveDataрозпоряджався б onStopфактично
arekolek

@arekolek з мого розуміння: навіть для обробки CompositeDispoablewe переписали методи життєвого циклу. Але в Live даних все буде включено в один рядок коду. Таким чином ми економимо мінімум 20 рядків коду.
Суреш

Ми можемо визначити baseFragment та визначити метод підписки Disposable [], який слід перекрити всіма похідними фрагментами, викликати цей метод у onCreateView і додати повернене значення в CompositeDisposable, розпорядитися цим в onDestroyView, не забувши більше.
android2013

Йдеться не лише про утилізацію. Використовуючи RxJava, вам потрібно розпоряджатися на onStop, після чого знову підписуватися на onStart / onResume, обробляти зміни конфігурації та робити купу інших речей. Ось чому так багато збоїв за допомогою RxJava. LiveData обробляє все це, але не такий гнучкий, як RxJava.
користувач932178

24

Як ви можете знати в реактивній екосистемі, у нас спостерігається спостереження, яке випромінює дані, і спостерігач, який підписується (отримує повідомлення) про цю спостережувану емісію, нічого дивного в тому, як працює так званий шаблон спостерігача. Спостерігаючий щось «кричить», спостерігач отримує сповіщення про те, що спостерігач кричить щось в даний момент.

Розглядайте LiveDataяк спостережуване, що дозволяє керувати спостерігачами, які перебувають у activeстані. Інакше кажучи LiveData, це просто спостерігається, але також піклується про життєвий цикл.

Але давайте розглянемо два випадки коду, які ви запитуєте:

А) Живі дані

Б) RXJava

A) Це основна реалізація 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.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 дозволяє постійно оновлювати кожну зміну спостерігача в режимі реального часу, щоб події управлялися в режимі реального часу там, де це потрібно. Для використання LiveDataнастійно рекомендується знати поняття життєвого циклу та відносні об'єкти LifeCycleOwner / LifeCycle , а також я б запропонував вам ознайомитись із Трансформаціями , якщо ви хочете реалізувати LiveDataреальні сценарії життя. Тут ви можете знайти деякі випадки використання із великого загального користування .

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

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


4

LiveData - це підмножина компонентів архітектури Android, розроблена командою Android.

З живими даними та іншими компонентами архітектури витоки пам'яті та інші подібні проблеми вирішуються компонентами архітектури. Оскільки він розроблений командою Android, він найкращий для android. Вони також надають оновлення для нових версій Android.

Якщо ви хочете використовувати лише в розробці додатків Android, перейдіть до компонентів архітектури Android. В іншому випадку, якщо ви хочете використовувати інший додаток Java, наприклад веб-додаток, настільний додаток тощо, використовуйте RxJava


Я намагався уточнити вашу відповідь. Якщо я яким-небудь чином суперечив вашому первинному наміру, сміливо редагуйте. Якщо ви все-таки зробите це, будь ласка, спробуйте зробити це більш зрозумілим, ніж початковий перегляд. Остання частина вашої відповіді чесно не мала сенсу.
Зої

2

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

Rx - потужний інструмент, який дозволяє вирішити проблему в елегантному декларативному стилі. Він обробляє варіанти бізнес-операцій або операції Service Api


0

Порівнюючи LiveData з RxJava - це порівняння яблук з фруктовими салатами.

Порівняйте LiveData з ContentObserver, і ви порівнюєте яблука з яблуками. LiveData фактично є заміною життєвого циклу ContentObserver.

Порівнюючи RxJava з AsyncTask або будь-яким іншим інструментом для нарізки різьби, порівнюємо фруктові салати з апельсинами, оскільки RxJava допомагає не тільки нарізати ниткою.


0
  • LiveData частково дорівнює предмету Rx або SharedRxObservable

  • LiveData керує життєвим циклом підписки, але підписка на Rx Subject повинна бути створена та розпоряджена вручну

  • LiveData не має стану завершення, але в темі Rx є OnError та OnCompleted

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.