我使用Retrofit为我的异步网络电话返回rxjava Observable。
我发现自己重复了以下调用:
someApiCall().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
似乎我总是订阅IO线程并观察Android主线程。这似乎是我发现的所有资源的最佳实践。也许除了长时间运行的计算之外,我不太明白何时我们想要偏离这种模式。
有没有办法通过默认subscribeOn和observeOn线程来删除这个样板?
这是rxjava plugins的用例吗? (我无法找到许多使用它们的例子。)
我可以通过弄乱retrofit executors吗?
来设置网络边界的默认线程答案 0 :(得分:13)
对于Observable
响应,Retrofit当前将subscribeOn
设置为RestAdapter
的HTTP执行程序(提供或默认)。这样做是为了将RxJava支持填充到现有行为中。
2.0的计划是提供明确设置subscribeOn
和observeOn
默认值的功能(无论是两者,只有一个,还是两者都没有。)
例如,如果您需要将多个API调用链接在一起,那么您不希望总是希望在主线程上进行观察的原因。
答案 1 :(得分:6)
Retrofit Version 2.0.0-beta2(2015-09-28)的Change Log显示 subscribeOn()是在后台运行所必需的。
修复:可观察和基于单一的请求执行现在同步运行(因此需要subscribeOn()才能在后台运行。)
答案 2 :(得分:4)
是,可以删除这两个电话。
以下是改进适配器类,它自动调度subscribeOn
和observedOn
以消除每次调用中对样板调用的需要:
public class RxThreadingCallAdapterFactory extends CallAdapter.Factory {
private final RxJava2CallAdapterFactory original;
private RxThreadingCallAdapterFactory() {
// Always call on background thread
original = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io());
}
public static CallAdapter.Factory create() {
return new RxThreadingCallAdapterFactory();
}
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxCallAdapterWrapper(original.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {
private final CallAdapter<?> wrapped;
public RxCallAdapterWrapper(CallAdapter<?> wrapped) {
this.wrapped = wrapped;
}
@Override
public Type responseType() {
return wrapped.responseType();
}
@Override
public <R> Observable<?> adapt(Call<R> call) {
Observable observable = (Observable) wrapped.adapt(call);
// Always handle result on main thread
return observable.observeOn(AndroidSchedulers.mainThread());
}
}
}
然后在配置改造时使用此适配器:
Retrofit.Builder()
.baseUrl(...)
.addCallAdapterFactory(RxThreadingCallAdapterFactory.create())
我写了this blog post,详细介绍了这里发生的事情。
这将删除两个调用,我认为是样板。我认为Jake将背景调用链接在一起并不真正适用的场景,因为在这种情况下我会进行改进同步调用而根本不使用调度程序。
答案 3 :(得分:0)
这不是您要查找的内容的完整答案,但这至少减轻了纠正subscribeOn(Schedulers.io())
retrofit = new Retrofit
.Builder()
.baseUrl(app.getUrlBase())
.client(httpClient)
.addCallAdapterFactory(
RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()) // <-- default subscribeOn()
)
.addConverterFactory(jsonFactory)
.build();