RxJava Tips

4644 ワード

本編は会社プロジェクト用のRxJavaで遭遇した問題を記録し、本編は更新を続けます!
RxJavaは文章に精通するまで入門することを極力お勧めしますhttps://github.com/THEONE10211024/RxJavaSamples
グループディスカッションへようこそ(158943444):
RxJava RxAndroid Retrofit RxBus Dragger2 OkHttp MVP MVVM DataBinding
1、メモリ漏洩防止ComponentSubscription
CompositeSubscriptionを使用すると、RxJavaによるメモリの漏洩を防ぐことができます.Rxストリームを使用する場所が多いので、CompositeSubscriptionをBasePresenterに直接置くと便利です.
  public class BasePresenter implements Presenter{    
    public CompositeSubscription mCompositeSubscription;    
    public T view;    
    @Override    
    public void attachView(T t) {        
      mCompositeSubscription = new CompositeSubscription();        
      view = t;    
    }    
    @Override    
    public void detachView() {        
      mCompositeSubscription.unsubscribe();        
      mCompositeSubscription = null;        
      view = null;    
    }    
    public T getView(){        
      return view;    
    }
  }

そして各Presenterでは、使用するRxJavaストリームをComponentSubscriptionに加えるだけでよい.add(RxJavaストリーム)では、RxJavaによるメモリの漏洩を心配する必要はありません.
2、スレッド切替composeの使用
RxJavaを使うのはすべて知っていて、スレッドの切り替えの时どんなに优雅です!のsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())
しかし、毎回このように書くのも面倒で、composeでもっと優雅にスレッドを切り替えることができます.Rxストリームの最後にcompose(RxUtils.applyIOToMainThreadSchedulers()という文で切り替えられます!
  public class RxUtils {    
    private staticObservable.TransformerioToMainThreadSchedulerTransformer;    
    private static Observable.Transformer newThreadToMainThreadSchedulerTransformer;    
    static {        
      ioToMainThreadSchedulerTransformer = createIOToMainThreadScheduler();        
      newThreadToMainThreadSchedulerTransformer = createNewThreadToMainThreadScheduler();
    }    
    private static  Observable.Transformer createIOToMainThreadScheduler() {        
      return tObservable -> tObservable.subscribeOn(Schedulers.io())    
              .unsubscribeOn(Schedulers.computation())               
              .observeOn(AndroidSchedulers.mainThread());    
    }    
    public static  Observable.Transformer applyIOToMainThreadSchedulers() {       
       return ioToMainThreadSchedulerTransformer;    
    }    
    private static  Observable.Transformer createNewThreadToMainThreadScheduler(){        
        return tObservable -> tObservable.subscribeOn(Schedulers.newThread())               
        .unsubscribeOn(Schedulers.computation())               
        .unsubscribeOn(Schedulers.io())               
        .observeOn(AndroidSchedulers.mainThread());    
    }    
    public static  Observable.Transformer applyNewThreadToMainThreadSchedulers(){        
      return newThreadToMainThreadSchedulerTransformer;   
   }
}

3、onErrorResumeNextの使用
シナリオ:私たちがデータを要求するときは、まずネットワーク上のデータを要求し、なければハードディスク上のデータを要求し、同じRxストリームでこれらの操作を処理したい.
方法:
onErrorResumeNextオペレータを使用すると、上記の要件をよく完了することができ、ネットワーク要求にonErrorResumeNext(throwable->getDisk()を加えることで、Rxストリーム全体が終了せず、getDiskがデータのキャッシュを要求するストリームに移行する.
1、onErrorResumeNextを使用しない場合、ネットワークに問題が発生した場合、ネットワークデータを要求するストリームはOnErrorを実行してRxストリーム全体を終了し、onErrorでキャッシュデータを要求するRxストリームをここで送信しなければならないので、面倒です.
2、concatオペレータを使用する、concatを使用してもネットワークデータを要求するRxストリームがOnErrorに実行されるまで待つ必要があり、二次実行要求キャッシュのRxストリームも同様に面倒である.
もっと良い方法があるかどうか分からないが、もしあるならば、伝言を望んで、ありがとうございます!
4、filterの1つの誤った理解
filterをよく理解していないので、filterがすべてのデータ(つまり自分の欲しいデータを得ていない)をフィルタリングしたらsubscribeのonErrorが実行されると思っていましたが、実はonCompleteが直接実行され、ストリーム全体が終了しました!テストコード:
  Observable.create(new Observable.OnSubscribe() {    
    @Override    
    public void call(Subscriber super Integer> subscriber) {        
      subscriber.onNext(null);        
      subscriber.onCompleted();    
      }
    })
    .filter(integer -> integer != null)        
    .subscribeOn(Schedulers.io())        
    .observeOn(AndroidSchedulers.mainThread())        
    .subscribe(new Subscriber() {            
        @Override            
        public void onCompleted() {                
          LogUtils.i("integer:");            
        }            
        @Override            
        public void onError(Throwable e) {                
          LogUtils.i("integer:" + e.getMessage());            
        }            
        @Override            
        public void onNext(Integer integer) {                
          LogUtils.i("integer:" + integer);            
        }        
    });