RxJava 1升級到RxJava 2過程中踩過的一些“坑”

RxJava2介紹

RxJava2 發佈已經有一段時間了,是對 RxJava 的一次重大的升級,由於我的一個庫cv4j使用了 RxJava2 來嚐鮮,但是 RxJava2 跟 RxJava1 是不能同時存在於一個項目中的,逼不得已我得把自己所有框架中使用 RxJava 的地方以及
App 中使用 RxJava 的地方都升級到最新版本。所以我整理並記錄了一些已經填好的坑。分享出來供大家參考學習,下面來看看詳細的介紹:

填坑記錄

1. RxJava1 跟 RxJava2 不能共存

如果,在同一個module中同時使用RxJava1和RxJava2,類似如下:

1

2

3

4

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'

那麼,很不幸你會遇到這樣的錯誤

同理,在 App 中如果使用了 Rxjava2,但是某個第三方的 library 還在使用 Rxjava1 也會遇到同樣的錯誤。

上面的錯誤是因爲 RxAndroid 2.0.1 本身依賴了 RxJava 2.0.1。我們嘗試去掉對 RxJava 的依賴,只留下 RxAndroid 。還是會遇到問題。

1

2

3

4

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'

所以使用RxAndroid不能去掉對RxJava的依賴,我是這樣使用的。

1

2

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

compile 'io.reactivex.rxjava2:rxjava:2.0.7'

官方也是這樣解釋的

1

2

Because RxAndroid releases are few and far between, it is recommended you also

explicitly depend on RxJava's latest version for bug fixes and new features.

最後,我建議要升級到 RxJava2 的時候必須所有使用的地方都要升級,並且用最新的版本。

2. 新增Flowable

RxJava1 中 Observable 不能很好地支持 backpressure ,會拋出MissingBackpressureException。所以在 RxJava2 中 Oberservable 不再支持 backpressure ,而使用新增的 Flowable 來支持 backpressure 。

Flowable的用法跟原先的Observable是一樣的。

3. ActionN 和 FuncN 改名

ActionN 和 FuncN 遵循Java 8的命名規則。
其中,Action0 改名成Action,Action1改名成Consumer,而Action2改名成了BiConsumer,而Action3 - Action9都不再使用了,ActionN變成了Consumer<Object[]> 。

同樣,Func改名成Function,Func2改名成BiFunction,Func3 - Func9 改名成 Function3 - Function9,FuncN 由 Function<Object[], R> 取代。

4. Observable.OnSubscribe 變成 ObservableOnSubscribe

原先RxJava1的寫法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

 }

});

現在的寫法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

 }

});

5. ObservableOnSubscribe 中使用 ObservableEmitter 發送數據給 Observer

結合上一條,ObservableOnSubscribe 不再使用 Subscriber 而是用 ObservableEmitter 替代。

ObservableEmitter 可以理解爲發射器,是用來發出事件的,它可以發出三種類型的事件,通過調用emitter的onNext(T value) onComplete()onError(Throwable error)可以分別發出next事件、complete事件和error事件。 如果只關心next事件的話,只需單獨使用onNext()即可。

需要特別注意,emitter的onComplete()調用後,Consumer不再接收任何next事件。

6. Observable.Transformer 變成 ObservableTransformer

原先RxJava1的寫法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

/**

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

  }

 };

}

現在的寫法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

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

  }

 };

}

由於新增了Flowable,同理也增加了FlowableTransformer

1

2

3

4

5

6

7

8

9

10

11

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

  }

 };

}

7. Subscription 改名爲 Disposable

在 RxJava2 中,由於已經存在了 org.reactivestreams.subscription 這個類,爲了避免名字衝突將原先的 rx.Subscription 改名爲 io.reactivex.disposables.Disposable 。

剛開始不知道,在升級 RxJava2 時發現 org.reactivestreams.subscription 這個類完全沒法做原先 rx.Subscription 的事情:(

順便說下,Disposable必須單次使用,用完就要銷燬。

8. first() 用法改變

官方文檔是這麼描述的first()的用法

 

1.x 2.x
first() RC3 renamed to firstElement and returns Maybe<T>
first(Func1) dropped, use filter(predicate).first()
firstOrDefault(T) renamed to first(T) and RC3 returns Single<T>
firstOrDefault(Func1, T) renamed to first(T) and RC3 returns Single<T>

 

first(Func1)爲例,first(Func1)後面還使用了push() ,原先 Rxjava1會這樣寫

1

2

3

4

5

6

7

8

ConnectableObservable<Data> connectableObservable = Observable

   .concat(Observable.from(list))

   .first(new Func1<Data, Boolean>() {

    @Override

    public Boolean call(Data data) {

     return DataUtils.isAvailable(data);

    }

   }).publish();

RxJava2 改成這樣

1

2

3

4

5

6

7

8

9

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

9. toBlocking().y 被 blockingY() 取代

在我的框架中存在着一個Optional類,它跟Java 8的Optional作用差不多,原先是使用RxJava1來編寫的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

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

 }

}

升級到RxJava2之後,get() 和 orElse() 方法都會報錯,修改之後是這樣的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

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

 }

}

10. PublishSubject

包括 PublishSubject 以及各種 Subject(ReplaySubject、BehaviorSubject、AsyncSubject) 都不再支持backpressure。

總結

RxJava2 所帶來的變化遠遠不止這些,以後遇到的話還會繼續整理和總結,畢竟我使用的 RxJava2 還是很少的一部分內容。

RxJava2 最好到文檔依然是官方文檔。如果是新項目到話,可以毫不猶豫地使用RxJava2,如果是在線上已經成熟穩定的項目,可以再等等。對於新手的話,可以直接從 RxJava2 學起,RxJava1 就直接略過吧。對於老手,RxJava2 還是使用原來的思想,區別不大,從 RxJava1 遷移到 Rxjava2 也花不了多少工夫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章