2015-10-31 10 views
8

レトロフィット、そして私のコード:私は私のAndroidアプリに<code>RxJava</code>と<code>Retrofit</code>を使用するデフォルトのスレッド

public void getConfig(NetworkSubscriber subscriber) { 
    Observable<Config> observable = mApi.getConfig(); 
    observable.subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(subscriber); 
} 

public void getCode(String mobile, int type, NetworkSubscriber subscriber) { 
    Observable<BaseMessageEntity> observable = mApi.getCode(mobile, type); 
    observable.subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(subscriber); 
} 

と私は.subscribeOn(Schedulers.newThread())を書きたくないと .observeOn(AndroidSchedulers.mainThread())

がどのように私が行うことができ、すべてのビジネスメソッド?

答えて

17

すべての呼び出しで必要なスレッドを指定しない場合は、RxJavaCallAdapterFactoryのラッパーを作成して、デフォルトでスレッドを設定することができます。その後、

public class RxThreadCallAdapter extends CallAdapter.Factory { 

    RxJavaCallAdapterFactory rxFactory = RxJavaCallAdapterFactory.create(); 
    private Scheduler subscribeScheduler; 
    private Scheduler observerScheduler; 

    public RxThreadCallAdapter(Scheduler subscribeScheduler, Scheduler observerScheduler) { 
     this.subscribeScheduler = subscribeScheduler; 
     this.observerScheduler = observerScheduler; 
    } 

    @Override 
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { 
     CallAdapter<Observable<?>> callAdapter = (CallAdapter<Observable<?>>) rxFactory.get(returnType, annotations, retrofit); 
     return callAdapter != null ? new ThreadCallAdapter(callAdapter) : null; 
    } 

    final class ThreadCallAdapter implements CallAdapter<Observable<?>> { 
     CallAdapter<Observable<?>> delegateAdapter; 

     ThreadCallAdapter(CallAdapter<Observable<?>> delegateAdapter) { 
      this.delegateAdapter = delegateAdapter; 
     } 

     @Override public Type responseType() { 
      return delegateAdapter.responseType(); 
     } 

     @Override 
     public <T> Observable<?> adapt(Call<T> call) { 
      return delegateAdapter.adapt(call).subscribeOn(subscribeScheduler) 
       .observeOn(observerScheduler); 
     } 
    } 
} 

とそれを使用する代わりに、あなたのビルダーでRxJavaCallAdapterFactory.create() -

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl("https://api.github.com/") 
    .addConverterFactory(GsonConverterFactory.create()) 
    .addCallAdapterFactory(new RxThreadCallAdapter(Schedulers.io(), AndroidSchedulers.mainThread())) 
    .build(); 
+0

考えてみよう!あなたは私を持っている! – xuyanjun

+0

このエラーはスレッド(IEカスタムアクセス管理)の中で呼び出しを行うと '' 'return delegateAdapter.responseType();' 'がnullポインタを返します。 –

6

compose()を使用すると、1行に減らすことができます。たとえば、getConfig()メソッドの修正版は次のとおりです。あなたがretrolambdaを使用していると仮定します。

public void getConfig(NetworkSubscriber subscriber) { 
    Observable<Config> observable = mApi.getConfig(); 
    observable 
      .compose(this::setupThreads) 
      .subscribe(subscriber); 
} 

setupThreads()方法は次のようになります。

private <T> Observable<T> setupThreads(final Observable<T> observable) { 
    return observable 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()); 
} 

数参照:

+0

ありがとう、私はそれを得た。しかし、それはrx自己によってそれを解決する方法ではありませんか? – xuyanjun

+0

@xuyanjun - 'compose()'はRxJavaの貴重な部分ですので、 "rx selfで解決する"ということをどういう意味かは分かりません。この場合、 'compose()'はすべての観測対象に '.subscribeOn(Schedulers.newThread())。observeOn(AndroidSchedulers.mainThread())'を追加することなく 'setupThreads()'を何度も再利用できるようにします。 。 – kjones

6

subscribeOnのデフォルトのスケジューラを持っているあなたのRetrofitインスタンスを作成するときにまっすぐRxJavaCallAdapterFactoryに引数として渡すことができます。レトロフィット2.0.0

new Retrofit.Builder() 
      .client(okHttpClient) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io())) 
      .build(); 

を導入ガット

関連する問題

 関連する問題