何时在Android中使用RxJava以及何时从Android Architectural Components使用LiveData?


Answers:


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的要点是,它使用库中提供的操作甚至您提供的自定义操作将控制和时序组合到一个Universe中。

LiveData仅解决该Universe的一小部分,相当于构建liveLocation


2
谢谢,LiveData文档似乎不再引用位置示例。这里还有更多有趣的地方(带有位置示例):androidkt.com/livedata
Daniel Wilson

5
@DanielWilson链接不再可用。
图拉

老兄,我不记得wtf在那个链接上:DI就像Mark Allison的实时数据示例代码一样: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 '18

119

关于最初的问题,RxJava和LiveData确实很好地互补。

LiveData与Android生命周期和紧密集成,在ViewModel层上大放异彩ViewModelRxJava提供更多的转换功能(如@Bob Dalgleish所述)。

当前,我们正在RxJava数据源和存储库层中LiveData使用它,并将其转换为LiveDataReactiveStreamsViewModels中的(使用)(在将数据暴露给活动/碎片之前)-对这种方法非常满意。


8
如果我们对您的理解正确,那么LiveData仅对特定于Android UI的实现有用。如果我们只是使用Clean Architecture构建通用应用程序,并与其他平台共享该架构,那么RxJava比LiveData更合适吗?
IgorGanapolsky '18年

@IgorGanapolsky您对通用应用程序使用什么语言/框架?
kzotin

独立于Android的API和用Java / Kotlin编写的Clean Arch。
IgorGanapolsky

1
您能否在答案中提出LiveDataReactiveStreams的任何可行示例?
Pawan

2
@kzotin你不需要那个observeOnLiveDataReactiveStreams通过打电话来做到LiveData.postValue()。并且不能保证您subscribeOn总体上会有任何效果。
arekolek

77

LiveData和RxJava之间有许多区别:

  1. LiveData不是STREAM,而在RxJava中,所有内容(实际上是一切)都是STREAM
  2. LiveData是可观察的数据持有者类。与常规的可观察对象不同,LiveData具有生命周期感知功能,这意味着它尊重其他应用程序组件(例如活动,片段或服务)的生命周期。这种意识确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者。
  3. LiveData是同步的,因此您不能像使用RxJava那样仅使用LiveData来异步执行大量代码(网络调用,数据库操作等)。
  4. 要充分利用此二重奏,您能做的最好的事情就是将RxJava用于业务逻辑(网络调用,数据处理等,以及在Repository之内和之外发生的任何事情),并将LiveData用于表示层。这样,您将获得业务逻辑的转换和流功能以及UI的生命周期感知操作。
  5. 如果一起使用,LiveData和RxJava会互相补充。我的意思是,使用RxJava进行所有操作,最后,当您要更新UI时,执行以下代码,将Observable更改为LiveData。因此,您的视图(UI)会观察到ViewModel中的LiveData,其中的LiveData就是非可变的MutableLiveData(或者MutableLiveData是可变的LiveData)。
  6. 所以这里的问题是,为什么首先还要使用LiveData? 如下面的代码所示,您将RxJava的响应存储到MutableLiveData(或LiveData)中,并且LiveData是生命周期感知的,因此在某种程度上,您的数据是生命周期感知的。现在,想象一下当数据本身知道何时以及何时不更新UI时的可能性。
  7. LiveData没有历史记录(仅是当前状态)。因此,您不应将LiveData用于聊天应用程序。
  8. 当将LiveData与RxJava一起使用时,不需要诸如MediatorLiveDataSwitchMap等之类的东西。它们是流控制工具,而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

您能解释一下实时数据如何同步吗?据我所知,我们可以将Livedata对象发送到另一个线程,然后该线程可以对观察者可以在MainThread中侦听的值进行后期处理。
Hitesh Bisht

如果您再次阅读我写的内容,则意味着您无法像使用RxJava一样使用LiveData来仅在另一个线程上工作(是的,即使在那里我也使用“ just”)
Abhishek Kumar,

生命周期不是LiveData的重要优势吗?您1.描述您的管道需要做什么以及最终结果是什么,2.订阅“观察”子句中的结果,然后3.管道仅在您的生命周期状态允许时才运行。
Srg

29

其实,LiveData 不是本质的不同工具RxJava,那么,为什么它推出了作为一个架构组件时RxJava,所有订阅储存的可观的可以很容易地管理生命周期的 CompositeDispoable 对象,然后在释放他们onDestroy()Activity 或者onDestroyView() 在中Fragment 只使用一个代码行?

通过使用RxJava一次构建一个电影搜索应用程序,然后在此处使用LiveData,我已经完全回答了这个问题。

简而言之,可以,但是除了拥有基本的生命周期知识外,还需要首先覆盖相关的生命周期方法。对于某些人来说,这可能仍然没有意义,但事实是,根据Google I / O 2018中的Jetpack会话之一,许多开发人员发现生命周期管理很复杂。由不处理生命周期依赖性引起的崩溃错误可能是另一个迹象,即即使开发人员知道生命周期,也忘记在他们的应用程序中使用的每个Activity / Fragment中都照顾好它。在大型应用程序中,这可能会成为一个问题,尽管它可能会对生产力产生负面影响。

最重要的是,通过引入LiveData,有望使更多的开发人员采用MVVM,甚至无需了解生命周期管理,内存泄漏和崩溃。即使我毫不怀疑,这在功能和赋予开发人员的功能,反应式编程方面LiveData都无法与之相比,RxJava并且RxJava是许多人难以理解的概念和工具。另一方面,我认为这并不是LiveData要替代RxJava它(它根本不可能),而是解决许多开发人员所遇到的有争议的广泛问题的非常简单的工具。

**更新**我在这里添加了一篇新文章其中我解释了滥用LiveData如何导致意外结果。在这种情况下,RxJava可以营救



2
“为什么引入RxJava可以轻松地通过将所有订阅存储在CompositeDispoable中然后将它们存储在Activity的onDestroy()中来管理生命周期的原因”- LiveDataonStop实际
放置-arekolek

据我了解,@ arekolek:即使处理CompositeDispoable,我们也已经覆盖了生命周期方法。但是在实时数据中,所有内容都将包含在一行代码中。因此,我们至少节省了20行代码。
Suresh '18

我们可以定义一个baseFragment并定义要被所有派生片段覆盖的Disposable [] subscriptions()方法,在onCreateView中调用此方法,并在CompositeDisposable中添加返回值,在onDestroyView中进行处理,不要忘记。
android2013

这不仅仅是关于处置。使用RxJava,您必须将其放置在onStop上,然后再次在onStart / onResume中进行订阅,处理配置更改,并进行其他操作。这就是使用RxJava导致崩溃如此之多的原因。LiveData可以处理所有这些,但不如RxJava灵活。
user932178

24

如您所知,在反应生态系统中,我们有一个Observable发出数据,一个Observer订阅(获得通知)这种Observable发射,所谓的Observer Pattern的工作原理并不奇怪。一个可观察的“喊”某事,观察者得到通知,在给定的时刻可观察的喊某事。

认为LiveData是一个Observable,可让您管理处于某种active状态的Observer 。在其他方面LiveData是一个简单的可观察,但也需要在生命周期的服务。

但是,让我们看看您请求的两种代码情况:

A)实时数据

B)接收Java

A)这是LiveData的基本实现

1)您通常在ViewModel中实例化LiveData以维护方向更改(您可以使用只读的LiveData或可写的MutableLiveData,因此通常将LiveData类暴露在外部)

2)在Main Activity(不是ViewModel)的OnCreate方法中,您“订阅”一个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
        })


        }
    }
}

B)这是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结合使用时,您可以实时更新Observer中的每个更改,以便在需要的地方实时管理事件。LiveData强烈建议您使用该工具以了解生命周期的概念以及相关对象LifeCycleOwner / LifeCycle,如果您想在现实生活中实现,我也建议您看一下TransformationsLiveData。在这里,您可以从通用软件中找到一些用例。

为了总结起来主要LiveData是简化的RXJava观察在多个成分的变化,而无需创建组件之间明确的所谓的相关性规则,一个优雅的方式,这样就可以测试更容易的代码,使之更具可读性。RXJava,允许您执行LiveData的操作以及更多操作。由于RXJava的扩展功能,您既可以将LiveData用于简单的情况,也可以利用RXJava的所有功能继续使用Android体系结构组件作为 ViewModel,当然这意味着RXJava要复杂得多,只要考虑拥有数百个运算符即可SwitchMap和LiveData的地图(目前)。

RXJava版本2是一个库,它彻底改变了面向对象的范例,增加了一种所谓的功能方式来管理程序流程。


4

LiveData是android团队开发的android体系结构组件的子集。

对于实时数据和其他体系结构组件,内存泄漏和其他类似问题由体系结构组件处理。由于它是由android团队开发的,因此最适合android。他们还提供处理新版本Android的更新。

如果您只想在Android应用程序开发中使用,请使用Android体系结构组件。否则,如果要使用其他Java应用程序(例如Web应用程序,桌面应用程序等),请使用RxJava


我试图澄清您的答案。如果我与您的原始意图有任何冲突,请随时进行编辑。如果您这样做,请尝试使其比初始版本更清晰。坦白地说,您的答案的最后一部分没有任何意义。
佐伊

2

LiveData作为数据持有者,别无其他。我们也可以说LiveData是生命周期感知的消费者。LiveData强烈建议您了解生命周期的概念以及相关的对象LifeCycleOwner / LifeCycle,您将获得业务逻辑的转换和流功能以及UI的生命周期感知操作。

Rx是功能强大的工具,可以用优雅的声明式样式解决问题。它处理业务方面的选择或服务Api操作


0

将LiveData与RxJava进行比较将苹果与水果沙拉进行了比较。

将LiveData与ContentObserver进行比较,就可以将Apple与Apple进行比较。LiveData实际上是ContentObserver的生命周期感知替代品。

将RxJava与AsyncTask或任何其他线程工具进行比较会将水果沙拉与橙子进行比较,因为RxJava不仅可以帮助线程。


0
  • LiveData部分等于Rx主题或SharedRxObservable

  • LiveData管理订阅的生命周期,但是应该手动创建和处置Rx Subject订阅

  • LiveData没有终止状态,但Rx主题具有OnError和OnCompleted

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.