在RxJava2中创建自定义运算符?

时间:2017-01-24 17:24:15

标签: rx-java2

我无法找到如何使用RxJava 2创建自定义运算符的示例。我已经考虑了一些方法:

  1. 使用Observable.create,然后从源可观察对象flatMap使用它。我可以让这个工作,但它感觉不对。我最终创建了一个静态函数,我提供了源Observable,然后在源上提供了flatMap。在OnSubscribe中,然后我实例化了一个传递发射器的对象,它处理和管理Observable / Emitter(因为它不是微不足道的,我希望所有内容都尽可能封装)。
  2. 创建ObservableOperator并将其提供给Observable.lift。我找不到RxJava 2的任何这样的例子。我必须调试我自己的例子,以确保我对上游和下游的理解是正确的。因为我在RxJava 2上找不到任何关于此的示例或文档,我有点担心我可能会意外地做一些我不应该做的事。
  3. 创建我自己的Observable类型。这似乎是底层运算符的工作原理,其中许多运算符扩展AbstractObservableWithUpstream。虽然这里有很多事情,但似乎很容易错过一些东西或做一些我不应该做的事情。我不确定我是否应该采取这样的方法。我逐步完成了心理过程,看起来很快就能变得毛茸茸。
  4. 我将继续推进选项#2,但认为值得问一下,支持这种方法的方法是在RxJava2中,并且还要查明是否有任何文档或示例。

2 个答案:

答案 0 :(得分:3)

不建议初学者编写操作符,并且可以通过现有操作符实现许多所需的流程模式。

你看过RxJava关于writing operators for 2.x的维基吗?我建议从上到下阅读。

  1. 使用lists()是可能的,但是大多数人使用它来发布带有for-each循环的create()的元素,而不是认识到List这样做。
  2. 我们保留了此扩展点,尽管RxJava 2运算符本身不使用Flowable.fromIterable。如果您想避免使用选项3的样板,那么您可以尝试this route
  3. 这是RxJava 2运营商的实现方式。 lift()只是一个小便利,external implementors不是必需的。

答案 1 :(得分:2)

这可能会对你有所帮助。我实现了运算符RxJava2来处理APiError。我用升降机操作员。

参见示例。

  public final class ApiClient implements ApiClientInterface {
    ...
      @NonNull
      @Override
      public Observable<ActivateResponse> activate(String email, EmailData emailLinkData) {
          return myApiService.activate(email, emailData)
                  .lift(getApiErrorTransformer())
                  .subscribeOn(Schedulers.io());
      }

      private <T>ApiErrorOperator<T> getApiErrorTransformer() {
          return new ApiErrorOperator<>(gson, networkService);
      }

  }

然后你可以找到自定义运算符

    public final class ApiErrorOperator<T> implements ObservableOperator<T, T> {
        private static final String TAG = "ApiErrorOperator";
        private final Gson gson;
        private final NetworkService networkService;

        public ApiErrorOperator(@NonNull Gson gson, @NonNull NetworkService networkService) {
            this.gson = gson;
            this.networkService = networkService;
        }

        @Override
        public Observer<? super T> apply(Observer<? super T> observer) throws Exception {
            return new Observer<T>() {
                @Override
                public void onSubscribe(Disposable d) {
                    observer.onSubscribe(d);
                }

                @Override
                public void onNext(T value) {
                    observer.onNext(value);
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "onError", e);

                if (e instanceof HttpException) {
                        try {
                            HttpException error = (HttpException) e;
                            Response response = error.response();
                            String errorBody = response.errorBody().string();

                            ErrorResponse errorResponse = gson.fromJson(errorBody.trim(), ErrorResponse.class);
                            ApiException exception = new ApiException(errorResponse, response);

                            observer.onError(exception);
                        } catch (IOException exception) {
                            observer.onError(exception);
                        }

                    } else if (!networkService.isNetworkAvailable()) {
                        observer.onError(new NetworkException(ErrorResponse.builder()
                                .setErrorCode("")
                                .setDescription("No Network Connection Error")
                                .build()));
                    } else {
                        observer.onError(e);
                    }
                }

                @Override
                public void onComplete() {
                    observer.onComplete();
                }
            };
        }
    }