我应该使用 Observable(RxJava2) 还是 Call (retrofit2)?
Should I use Observable(RxJava2) or Call (retrofit2)?
TL;DR: 我想执行多个 Call
s (Retrofit) 就像你可以 .zip()
多个 Observable
s (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) { }
});
现在我想一次执行多个 Call
s(获取多个书名)并在所有请求完成时收到通知。这是我缺少知识的时候。
我知道我可以开始使用 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 以及您是否愿意使用协程。
编辑:
(从评论中回答你的问题)
如果你真的考虑 Calls
和 RxJava
Observables
你真的不需要做任何事情 more 使用 RxJava
。使用原始 Calls
时,您仍然需要:
- 如果你想触摸
Views
(observeOn(AndroidSchedulers.mainThread())
) ,请确保你在正确的线程上
- 确保您在正确的线程上接触网络 (
subscribeOn(Schedulers.io())
)
- 当你的
Activity
/Fragment
/Something else
不再存在时,确保你没有使用响应(处理 [=12 中的 Disposable
=] 处理)
您可以显着简化示例:
- 不要创建
Observable
和 Observer
。只需使用 subscribe
方法即 returns Disposable
。然后只维护这个 Disposable
.
- 你可能不需要
onComplete
所以你可以使用更简单的 .subscribe(...)
- 您可以通过在构建
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 -> {
});
TL;DR: 我想执行多个 Call
s (Retrofit) 就像你可以 .zip()
多个 Observable
s (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) { }
});
现在我想一次执行多个 Call
s(获取多个书名)并在所有请求完成时收到通知。这是我缺少知识的时候。
我知道我可以开始使用 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 以及您是否愿意使用协程。
编辑: (从评论中回答你的问题)
如果你真的考虑 Calls
和 RxJava
Observables
你真的不需要做任何事情 more 使用 RxJava
。使用原始 Calls
时,您仍然需要:
- 如果你想触摸
Views
(observeOn(AndroidSchedulers.mainThread())
) ,请确保你在正确的线程上
- 确保您在正确的线程上接触网络 (
subscribeOn(Schedulers.io())
) - 当你的
Activity
/Fragment
/Something else
不再存在时,确保你没有使用响应(处理 [=12 中的Disposable
=] 处理)
您可以显着简化示例:
- 不要创建
Observable
和Observer
。只需使用subscribe
方法即 returnsDisposable
。然后只维护这个Disposable
. - 你可能不需要
onComplete
所以你可以使用更简单的.subscribe(...)
- 您可以通过在构建
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 -> {
});