Android上rxjava的默认调度程序

时间:2014-07-16 19:14:00

标签: java android multithreading retrofit rx-java

我使用Retrofit为我的异步网络电话返回rxjava Observable。

我发现自己重复了以下调用:

someApiCall().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

似乎我总是订阅IO线程并观察Android主线程。这似乎是我发现的所有资源的最佳实践。也许除了长时间运行的计算之外,我不太明白何时我们想要偏离这种模式。

有没有办法通过默认subscribeOn和observeOn线程来删除这个样板?

这是rxjava plugins的用例吗? (我无法找到许多使用它们的例子。)

我可以通过弄乱retrofit executors吗?

来设置网络边界的默认线程

4 个答案:

答案 0 :(得分:13)

对于Observable响应,Retrofit当前将subscribeOn设置为RestAdapter的HTTP执行程序(提供或默认)。这样做是为了将RxJava支持填充到现有行为中。

2.0的计划是提供明确设置subscribeOnobserveOn默认值的功能(无论是两者,只有一个,还是两者都没有。)

例如,如果您需要将多个API调用链接在一起,那么您不希望总是希望在主线程上进行观察的原因。

答案 1 :(得分:6)

Retrofit Version 2.0.0-beta2(2015-09-28)的Change Log显示 subscribeOn()是在后台运行所必需的。

  

修复:可观察和基于单一的请求执行现在同步运行(因此需要subscribeOn()才能在后台运行。)

答案 2 :(得分:4)

,可以删除这两个电话。

以下是改进适配器类,它自动调度subscribeOnobservedOn以消除每次调用中对样板调用的需要:

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();