何时在 Android 中使用 RxJava,何时使用 Android 架构组件中的 LiveData?

When to use RxJava in Android and when to use LiveData from Android Architectural Components?

我没有得到在 Android 中使用 RxJava 和 Android 中使用 LiveData 的理由 Architectural Components.It 如果用例和两者之间的差异得到解释以及代码形式的示例,解释了两者之间的差异。

Android LiveData 是原始观察者模式的变体,增加了 active/inactive 转换。因此,它的范围非常有限。

使用 Android LiveData 中描述的示例,创建一个 class 来监视位置数据,并根据应用程序状态注册和注销。

RxJava 提供了更通用的运算符。假设此可观察对象将提供位置数据:

Observable<LocationData> locationObservable;

可以使用 Observable.create() 映射回调操作来构建可观察对象的实现。当 observable 被订阅时,回调被注册,当它被取消订阅时,回调被注销。该实现看起来与示例中提供的代码非常相似。

我们还假设您有一个在应用程序处于活动状态时发出 true 的可观察对象:

Observable<Boolean> isActive;

那么你可以通过以下方式提供LiveData的所有功能

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

switchMap() 运算符将以流的形式提供当前位置,如果应用程序未处于活动状态,则不提供任何内容。一旦你有了 liveLocation observable,你可以使用 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,它在 ViewModels 中转换为 LiveData(使用 LiveDataReactiveStreams)(在将数据公开到 [=22 之前) =]) - 对这种方法很满意。

您可能知道,在反应式生态系统中,我们有一个 Observable 发出数据和一个 Observer 订阅(接收通知)这个 Observable emission,没有什么奇怪的是所谓的观察者模式是如何工作的。一个 Observable "shouts"something,Observer 会收到通知,Observable 在给定时刻喊出一些东西。

LiveData 视为允许您管理处于 active 状态的观察者的 Observable。换句话说,LiveData 是一个简单的 Observable ,而且 负责生命周期。

但是让我们看看您请求的两个代码案例:

A) 实时数据

B) RXJava

A)这是LiveData的基本实现

1) 您通常在 ViewModel 中实例化 LiveData 以保持方向变化(您可以拥有只读的 LiveData,或可写的 MutableLiveData,因此您通常会暴露在 class LiveData 之外)

2) 在 Main Activity 的 OnCreate 方法中(不是 ViewModel) 你 "subscribe" 一个 Observer 对象(通常是一个 onChanged 方法)

3) 你启动方法观察建立link

首先 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) 你用 Observer

订阅 Observable
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);
       }
    });

特别是 LiveDataLifecycle 一起使用,并且经常与 ViewModel(如我们所见)架构组件一起使用。事实上,当 LiveData 与 ViewModel 结合使用时,您可以 实时更新 Observer 中的每个更改, 以便在需要时实时管理事件。强烈建议使用 LiveData 了解 lifecycle and the relative objects LifeCycleOwner/LifeCycle, also I would suggest you to have a look at Transformations, if you want to implement LiveData in real life scenarios. Here you can find some use cases from the great commonsware.

的概念

总结 基本上 LiveData 是一个简化的 RXJava,一种观察变化的优雅方式多个组件而不在组件之间创建显式所谓的依赖关系规则,这样您就可以更轻松地测试代码并使其更具可读性。 RXJava,允许你做 LiveData 的事情等等。由于 RXJava 的扩展功能,您既可以将 LiveData 用于简单的情况,也可以利用 RXJava 的所有功能继续使用 Android 架构组件作为 ViewModel,当然这意味着 RXJava可能要复杂得多,想想有数百个运算符而不是 LiveData 的 SwitchMap 和 Map(目前)。

RXJava 版本 2 是一个彻底改变了面向对象范式的库,添加了一种所谓的函数式方法来管理程序流。

事实上,LiveDataRxJava 并没有本质上的不同,所以当 RxJava 可以通过存储所有内容轻松管理生命周期时,为什么将它作为架构组件引入?订阅 CompositeDispoable 对象中的可观察对象,然后仅使用一行代码将它们放置在 ActivityonDestroy()FragmentonDestroyView() 中?

我已经使用 RxJava 构建了一个电影搜索应用程序,然后使用 LiveData here

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

最重要的是,通过引入 LiveData ,更多的开发人员有望采用 MVVM,甚至不必了解生命周期管理、内存泄漏和崩溃。尽管我毫不怀疑 LiveData 在能力和它赋予开发人员的力量方面无法与 RxJava 相提并论,但反应式编程和 RxJava 是一个难以理解的概念,并且许多人的工具。另一方面,我认为 LiveData 并不是要替代 RxJava——它根本不能——而是一个非常简单的工具,用于处理许多开发人员遇到的有争议的广泛问题。

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


LiveData 是 android 架构组件的子集,由 android 团队开发。

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

如果您只想在 Android 应用程序开发中使用,请选择 Android 架构组件。否则,如果您想使用其他 Java 应用程序,例如网络应用程序、桌面应用程序等,请使用 RxJava

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

Rx 是一个强大的工具,能够以优雅的声明式方式解决问题。它处理业务方选项或服务 Api 操作

LiveData和RxJava有很多不同:

  1. LiveData 不是 STREAM,而在 RxJava 中一切(字面上的一切)都是 STREAM
  2. LiveData 是一个可观察的数据持有者class。与常规的可观察对象不同,LiveData 具有生命周期感知能力,这意味着它尊重其他应用程序组件(例如活动、片段或服务)的生命周期。这种意识确保 LiveData 仅更新处于活动生命周期状态的应用程序组件观察者。
  3. LiveData 是同步的,所以你不能像使用 RxJava 那样仅使用 LiveData 异步执行一大块代码(网络调用、数据库操作等)。
  4. 你能做的最好的事情就是将 RxJava 用于你的业务逻辑(网络调用、数据操作等,任何发生在 Repository 之外的事情) ) 并将 LiveData 用于您的表示层。通过这种方式,您可以获得业务逻辑的转换和流功能以及 UI.
  5. 的生命周期感知操作
  6. LiveData 和 RxJava 相得益彰 如果一起使用。我的意思是,用 RxJava 做所有事情,最后当你想更新 UI 时,做一些类似于下面给出的代码将你的 Observable 变成 LiveData。因此,您的视图 (UI) 观察 ViewModel 中的 LiveData,其中您的 LiveData 只是不可变的 MutableLiveData(或者 MutableLiveData 是可变的 LiveData)。
  7. 所以这里的问题是,你为什么要一开始就使用 LiveData? 正如您在下面的代码中看到的,您将 RxJava 的响应存储到 MutableLiveData(或 LiveData),并且您的 LiveData 是生命周期感知的,因此在某种程度上,您的数据是生命周期感知的。现在,想象一下当您的数据本身知道何时以及何时不更新 UI.
  8. 的可能性
  9. LiveData 没有历史记录(只有当前状态)。因此,您不应该将 LiveData 用于聊天应用程序。
  10. 当你将 LiveData 与 RxJava 一起使用时,你不需要 MediatorLiveDataSwitchMap 等东西。它们是流控制工具和 RxJava在这方面要好很多倍。
  11. 将 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();
         }
    }

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

将 LiveData 与 ContentObserver 进行比较,您就是在同类比较。 LiveData 有效地成为 ContentObserver 的生命周期感知替代品。

将 RxJava 与 AsyncTask 或任何其他线程工具进行比较就像将水果沙拉与橙子进行比较,因为 RxJava 不仅有助于线程。

  • LiveData 部分等于 Rx Subject 或 SharedRxObservable

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

  • LiveData 没有终止状态但是 Rx Subject 有 OnError 和 OnCompleted