我应该使用 Observable(RxJava2) 还是 Call (retrofit2)?

Should I use Observable(RxJava2) or Call (retrofit2)?

TL;DR: 我想执行多个 Calls (Retrofit) 就像你可以 .zip() 多个 Observables (RxJava2).


我有一个 retrofit2 函数:

@GET("/data/price")
Call<JsonObject> getBookTitle(@Query("id") String id, @Query("lang") String lang);

我可以用 enquene():

在代码中执行它(异步)
ApiProvider.getBooksAPI().getBookTitle(bookId, "en").enqueue(new Callback<JsonObject>() {
    @Override
    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { }

    @Override
    public void onFailure(Call<JsonObject> call, Throwable t) { }
});

现在我想一次执行多个 Calls(获取多个书名)并在所有请求完成时收到通知。这是我缺少知识的时候。

我知道我可以开始使用 Observable (RXJava2) 而不是 Call (Retrofit2):

@GET("/data/price")
Observable<JsonObject> getBookTitle(@Query("id") String id, @Query("lang") String lang);

然后像下面的例子一样合并调用。但是这段代码似乎更加复杂和冗长(特别是如果我只需要 1 个书名)。有什么办法可以不使用 Observable 来合并 Call 吗?

List<Observable<JsonObject>> mergedCalls = new ArrayList<>();
mergedCalls.add(ApiProvider.getBooksAPI().getBookTitle(bookId1, "en"));
mergedCalls.add(ApiProvider.getBooksAPI().getBookTitle(bookId2, "en"));
mergedCalls.add(ApiProvider.getBooksAPI().getBookTitle(bookId3, "en"));

Observable<List<JsonObject>> observable = Observable.zip(calls, responses -> { 
        // merge responses, return List
        ...
    })
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io());

observer = new DisposableObserver<List<JsonObject>> () {
    @Override
    public void onNext(List<JsonObject> result) { // got all API results }

    @Override
    public void onError(Throwable e) { }

    @Override
    public void onComplete() { }
};

observable.subscribe(observer);

使用 RxJava 合并 Retrofit Calls 的简单方法。通过 enqueuing 手动合并 Calls all Calls 并在它们全部调用 onResponse 时做一些事情可能比简单地使用 Observable.zip(...).[=42 更复杂=]

您的另一种选择是使用 Kotlin 协程(现在 Retrofit 已经对它们提供了开箱即用的支持)。但这取决于您的代码中是否存在 Kotlin 以及您是否愿意使用协程。


编辑: (从评论中回答你的问题)

如果你真的考虑 CallsRxJava Observables 你真的不需要做任何事情 more 使用 RxJava。使用原始 Calls 时,您仍然需要:

  1. 如果你想触摸 Views (observeOn(AndroidSchedulers.mainThread()))
  2. ,请确保你在正确的线程上
  3. 确保您在正确的线程上接触网络 (subscribeOn(Schedulers.io()))
  4. 当你的 Activity/Fragment/Something else 不再存在时,确保你没有使用响应(处理 [=12 中的 Disposable =] 处理)

您可以显着简化示例:

  1. 不要创建 ObservableObserver。只需使用 subscribe 方法即 returns Disposable。然后只维护这个 Disposable.
  2. 你可能不需要 onComplete 所以你可以使用更简单的 .subscribe(...)
  3. 您可以通过在构建 Retrofit 实例时正确创建 RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()) 来消除对 .subscribeOn(Schedulers.io()) 的需求。
BooksApi booksApi = ApiProvider.getBooksAPI();
List<Observable<JsonObject>> mergedCalls = new ArrayList<>();
mergedCalls.add(booksApi.getBookTitle(bookId1, "en"));
mergedCalls.add(booksApi.getBookTitle(bookId2, "en"));
mergedCalls.add(booksApi.getBookTitle(bookId3, "en"));

final Disposable disposable = Observable
        .zip(mergedCalls, responses -> {
            // merge responses, return List
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(list -> {
            // got all API results
        }, throwable -> {

        });

为一个电话执行此操作将非常简单:

final Disposable disposable = booksApi
        .getBookTitle(bookId1, "en")
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(title -> {
            // got the result
        }, throwable -> {

        });