15

Retrofit を使用して、非同期ネットワーク呼び出しの rxjava Observable を返しています。

私は次の呼び出しを繰り返していることに気づきました。

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

私は常に IO スレッドをサブスクライブし、Android のメイン スレッドを監視しているようです。これは、私が見つけたすべてのリソースが推奨しているベスト プラクティスのようです。おそらく長時間の計算を除けば、いつこのパターンから逸脱したいのかよくわかりません。

subscribeOn スレッドと observeOn スレッドをデフォルトにすることで、このボイラープレートを削除する方法はありますか?

これはrxjava プラグインの使用例ですか? (それらの使用例はあまり見つかりません。)

retrofit executorをいじって、ネットワーク境界でデフォルトのスレッドを設定できますか?

4

4 に答える 4

14

応答の場合Observable、Retrofit は現在、 を(提供されたものまたはデフォルトの)subscribeOnの HTTP エグゼキューターとして設定します。RestAdapterこれは、RxJava サポートを既存の動作に組み込むために行われました。

2.0 の計画は、両方のデフォルトを明示的に設定する機能を提供することですsubscribeOn(observeOn両方であるか、1 つだけであるか、どちらでもないか)。

たとえば、複数の API 呼び出しを連鎖させる必要がある場合は、メイン スレッドを常に監視する必要はありません。

于 2014-07-17T16:45:26.253 に答える
6

Retrofit バージョン 2.0.0-beta2 (2015-09-28)の変更ログは、バックグラウンドで実行するにはsubscribeOn()が必要であることを示しています。

修正: リクエストの監視可能な単一ベースの実行が同期的に動作するようになりました (したがって、バックグラウンドで実行するには subscribeOn() が必要です)。

于 2015-11-25T08:11:24.640 に答える
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())

私は、ここで何が起こっているのかを詳しく説明するこのブログ投稿を書きました。

これにより、ボイラープレートと見なされる両方の呼び出しが削除されます。バックグラウンド呼び出しを連鎖させる Jake のシナリオは実際には当てはまらないと考えています。この場合、同期呼び出しを後付けし、スケジューラをまったく使用しないためです。

于 2016-11-27T12:03:40.260 に答える