RxJava1 升级到 RxJava2 所踩过的坑

GingerMcnei 8年前
   <h2>RxJava2</h2>    <p>RxJava2 发布已经有一段时间了,是对 RxJava 的一次重大的升级,由于我的一个库 <a href="/misc/goto?guid=4959742232719862892" rel="nofollow,noindex">cv4j</a> 使用了 RxJava2 来尝鲜,但是 RxJava2 跟 RxJava1 是不能同时存在于一个项目中的,逼不得已我得把自己所有框架中使用 RxJava 的地方以及</p>    <p>App 中使用 RxJava 的地方都升级到最新版本。所以我整理并记录了一些已经填好的坑。</p>    <h2>填坑记录</h2>    <h2>1. RxJava1 跟 RxJava2 不能共存</h2>    <p>如果,在同一个module中同时使用RxJava1和RxJava2,类似如下:</p>    <pre>  <code class="language-java">compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  compile 'io.reactivex.rxjava2:rxjava:2.0.7'  compile 'io.reactivex:rxandroid:1.2.0'  compile 'io.reactivex:rxjava:1.1.5'</code></pre>    <p>那么,很不幸你会遇到这样的错误</p>    <p><img src="https://simg.open-open.com/show/5481e04ced3323943bb9d88c2c80d541.jpg"></p>    <p>Rxjava1和Rxjava2无法共存.jpeg</p>    <p>同理,在 App 中如果使用了 Rxjava2,但是某个第三方的 library 还在使用 Rxjava1 也会遇到同样的错误。</p>    <p>上面的错误是因为 RxAndroid 2.0.1 本身依赖了 RxJava 2.0.1。我们尝试去掉对 RxJava 的依赖,只留下 RxAndroid 。还是会遇到问题。</p>    <pre>  <code class="language-java">compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  //compile 'io.reactivex.rxjava2:rxjava:2.0.7'  compile 'io.reactivex:rxandroid:1.2.0'  //compile 'io.reactivex:rxjava:1.1.5'</code></pre>    <p><img src="https://simg.open-open.com/show/4233d8aa664602ec5da87fae776edffc.jpg"></p>    <p>去掉对Rxjava的依赖.jpeg</p>    <p>所以使用RxAndroid不能去掉对RxJava的依赖,我是这样使用的。</p>    <pre>  <code class="language-java">compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  compile 'io.reactivex.rxjava2:rxjava:2.0.7'</code></pre>    <p>官方也是这样解释的</p>    <p>Because RxAndroid releases are few and far between, it is recommended you also</p>    <p>explicitly depend on RxJava's latest version for bug fixes and new features.</p>    <p>最后,我建议要升级到 RxJava2 的时候必须所有使用的地方都要升级,并且用最新的版本。</p>    <h2>2. 新增Flowable</h2>    <p>RxJava1 中 Observable 不能很好地支持 backpressure ,会抛出MissingBackpressureException。所以在 RxJava2 中 Oberservable 不再支持 backpressure ,而使用新增的 Flowable 来支持 backpressure 。</p>    <p>Flowable的用法跟原先的Observable是一样的。</p>    <h2>3. ActionN 和 FuncN 改名</h2>    <p>ActionN 和 FuncN 遵循Java 8的命名规则。</p>    <p>其中,Action0 改名成Action,Action1改名成Consumer,而Action2改名成了BiConsumer,而Action3 - Action9都不再使用了,ActionN变成了Consumer<Object[]>。</p>    <p>同样,Func改名成Function,Func改名成BiFunction,Func3 - Func9 改名成 Function3 - Function9,FuncN 由 Function<Object[], R> 取代。</p>    <h2>4. Observable.OnSubscribe 变成 ObservableOnSubscribe</h2>    <p>原先RxJava1的写法:</p>    <pre>  <code class="language-java">Observable.create(new Observable.OnSubscribe<String>() {                @Override              public void call(Subscriber<? super String> subscriber) {                  subscriber.onNext("hello");              }            }).subscribe(new Action1<String>() {                @Override              public void call(String s) {                  System.out.println(s);              }          });</code></pre>    <p>现在的写法:</p>    <pre>  <code class="language-java">Observable.create(new ObservableOnSubscribe<String>() {                @Override              public void subscribe(ObservableEmitter<String> e) throws Exception {                  e.onNext("hello");              }            }).subscribe(new Consumer<String>() {                @Override              public void accept(String s) {                  System.out.println(s);              }          });</code></pre>    <h2>5. ObservableOnSubscribe 中使用 ObservableEmitter 发送数据给 Observer</h2>    <p>结合上一条,ObservableOnSubscribe 不再使用 Subscriber 而是用 ObservableEmitter 替代。</p>    <p>ObservableEmitter 可以理解为发射器,是用来发出事件的,它可以发出三种类型的事件,通过调用emitter的onNext(T value)、onComplete()和onError(Throwable error)可以分别发出next事件、complete事件和error事件。 如果只关心next事件的话,只需单独使用onNext()即可。</p>    <p>需要特别注意,emitter的onComplete()调用后,Consumer不再接收任何next事件。</p>    <h2>6. Observable.Transformer 变成 ObservableTransformer</h2>    <p>原先RxJava1的写法:</p>    <pre>  <code class="language-java">/**       * 跟compose()配合使用,比如ObservableUtils.wrap(obj).compose(toMain())       * @param <T>       * @return       */      public static <T> Observable.Transformer<T, T> toMain() {          return new Observable.Transformer<T, T>() {             @Override              public Observable<T> call(Observable<T> tObservable) {                  return tObservable                          .subscribeOn(Schedulers.io())                          .observeOn(AndroidSchedulers.mainThread());              }          };      }</code></pre>    <p>现在的写法:</p>    <pre>  <code class="language-java">/**       * 跟compose()配合使用,比如ObservableUtils.wrap(obj).compose(toMain())       * @param <T>       * @return       */      public static <T> ObservableTransformer<T, T> toMain() {            return new ObservableTransformer<T, T>() {                @Override              public ObservableSource<T> apply(Observable<T> upstream) {                  return upstream.subscribeOn(Schedulers.io())                          .observeOn(AndroidSchedulers.mainThread());              }          };      }</code></pre>    <p>由于新增了Flowable,同理也增加了FlowableTransformer</p>    <pre>  <code class="language-java">public static <T> FlowableTransformer<T, T> toMain() {            return new FlowableTransformer<T, T>() {                @Override              public Publisher<T> apply(Flowable<T> upstream) {                  return upstream.subscribeOn(Schedulers.io())                          .observeOn(AndroidSchedulers.mainThread());              }          };      }</code></pre>    <h2>7. Subscription 改名为 Disposable</h2>    <p>在 RxJava2 中,由于已经存在了 org.reactivestreams.subscription 这个类,为了避免名字冲突将原先的 rx.Subscription 改名为 io.reactivex.disposables.Disposable。</p>    <p>刚开始不知道,在升级 RxJava2 时发现 org.reactivestreams.subscription 这个类完全没法做原先 rx.Subscription 的事情:(</p>    <p>顺便说下,Disposable必须单次使用,用完就要销毁。</p>    <h2>8. first() 用法改变</h2>    <p>官方文档是这么描述的first()的用法</p>    <table>     <thead>      <tr>       <th>1.x</th>       <th>2.x</th>      </tr>     </thead>     <tbody>      <tr>       <td>first()</td>       <td>RC3 renamed to firstElement and returns Maybe<T></td>      </tr>      <tr>       <td>first(Func1)</td>       <td>dropped, use filter(predicate).first()</td>      </tr>      <tr>       <td>firstOrDefault(T)</td>       <td>renamed to first(T) and RC3 returns Single<T></td>      </tr>      <tr>       <td>firstOrDefault(Func1, T)</td>       <td>renamed to first(T) and RC3 returns Single<T></td>      </tr>     </tbody>    </table>    <p>以first(Func1)为例,first(Func1)后面还使用了push(),原先 Rxjava1会这样写</p>    <pre>  <code class="language-java">ConnectableObservable<Data> connectableObservable = Observable.concat(Observable.from(list)).first(new Func1<Data, Boolean>() {                  @Override                  public Boolean call(Data data) {                      return DataUtils.isAvailable(data);                  }              }).publish();</code></pre>    <p>RxJava2 改成这样</p>    <pre>  <code class="language-java">ConnectableObservable<Data> connectableObservable = Observable.concat(Observable.fromIterable(list)).filter(new Predicate<Data>() {                    @Override                  public boolean test(@NonNull Data data) throws Exception {                      return DataUtils.isAvailable(data);                  }              }).firstElement().toObservable().publish();</code></pre>    <h2>9. toBlocking().y 被 blockingY() 取代</h2>    <p>在我的框架中存在着一个Optional类,它跟Java 8的Optional作用差不多,原先是使用RxJava1来编写的。</p>    <pre>  <code class="language-java">import rx.Observable;    /**   * 使用方法:   *         String s = null;   *         Optional.ofNullable(s).orElse("default")); // 如果s为null,则显示default,否则显示s的值   * @author Tony Shen   *   */  public class Optional<T> {        Observable<T> obs;        public Optional(Observable<T> obs) {          this.obs = obs;      }        public static <T> Optional<T> of(T value) {          if (value == null) {              throw new NullPointerException();          } else {              return new Optional<T>(Observable.just(value));          }      }        public static <T> Optional<T> ofNullable(T value) {          if (value == null) {              return new Optional<T>(Observable.<T>empty());          } else {              return new Optional<T>(Observable.just(value));          }      }        public T get() {          return obs.toBlocking().single();      }        public T orElse(T defaultValue) {          return obs.defaultIfEmpty(defaultValue).toBlocking().single();      }  }</code></pre>    <p>升级到RxJava2之后,get() 和 orElse() 方法都会报错,修改之后是这样的。</p>    <pre>  <code class="language-java">import io.reactivex.Observable;    /**   * 使用方法:   *         String s = null;   *         Optional.ofNullable(s).orElse("default"); // 如果s为null,则显示default,否则显示s的值   * @author Tony Shen   *   */  public class Optional<T> {        Observable<T> obs;        public Optional(Observable<T> obs) {          this.obs = obs;      }        public static <T> Optional<T> of(T value) {          if (value == null) {              throw new NullPointerException();          } else {              return new Optional<T>(Observable.just(value));          }      }        public static <T> Optional<T> ofNullable(T value) {          if (value == null) {              return new Optional<T>(Observable.<T>empty());          } else {              return new Optional<T>(Observable.just(value));          }      }        public T get() {            return obs.blockingSingle();      }        public T orElse(T defaultValue) {            return obs.defaultIfEmpty(defaultValue).blockingSingle();      }  }</code></pre>    <h2>10. PublishSubject</h2>    <p>包括 PublishSubject 以及各种 Subject(ReplaySubject、BehaviorSubject、AsyncSubject) 都不再支持backpressure。</p>    <h2>总结</h2>    <p>RxJava2 所带来的变化远远不止这些,以后遇到的话还会继续整理和总结,毕竟我使用的 RxJava2 还是很少的一部分内容。</p>    <p>RxJava2 最好到文档依然是官方文档。如果是新项目到话,可以毫不犹豫地使用RxJava2,如果是在线上已经成熟稳定的项目,可以再等等。对于新手的话,可以直接从 RxJava2 学起,RxJava1 就直接略过吧。对于老手,RxJava2 还是使用原来的思想,区别不大,从 RxJava1 迁移到 Rxjava2 也花不了多少工夫。</p>    <p>参考资料:</p>    <ol>     <li><a href="/misc/goto?guid=4959631832560174430" rel="nofollow,noindex">https://github.com/ReactiveX/RxJava/wiki</a></li>     <li><a href="/misc/goto?guid=4959724268622547531" rel="nofollow,noindex">https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0</a></li>     <li><a href="/misc/goto?guid=4959742232872487173" rel="nofollow,noindex">http://www.dundunwen.com/article/275b1d92-f9da-4bb8-b111-3aa8a6ace245.html</a></li>    </ol>    <p> </p>    <p>来自:http://www.jianshu.com/p/6d644ca1678f</p>    <p> </p>