用RxJava中的observable替换回调

时间:2017-02-08 16:39:26

标签: java rx-java

我使用侦听器作为回调来观察Android的异步操作,但我认为用RxJava替换这个侦听器可能会很棒,我很喜欢使用这个库但我真的很喜欢它而且我总是在Android项目中使用它。

以下是重构的代码:

public void getData( final OnResponseListener listener ){
   if(data!=null && !data.isEmpty()){
       listener.onSuccess();
   }
   else{
       listener.onError();
   }
}

一个简单的回调:

public interface OnResponseListener {
   public void onSuccess();
   public void onError(); 
}

"观察者":

object.getData( new OnResponseListener() {
    @Override
    public void onSuccess() {
       Log.w(TAG," on success");
    }

    @Override
    public void onError() {
       Log.e(TAG," on error");
    }
});

谢谢!

4 个答案:

答案 0 :(得分:15)

例如,您可以使用 Observable.fromCallable 为您的数据创建observable。

public Observable<Data> getData(){
    return Observable.fromCallable(() -> {
        Data result = null;
        //do something, get your Data object
        return result;
    });
}

然后使用您的数据

 getData().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(data -> {
                //do something with your data
            }, error -> {
                //do something on error
            });

使用rxjava 1.x和lambda表达式。

修改

如果我理解你,你想要替换那个监听器,而不是将它包装成可观察的。我在参考你的评论时添加了其他例子。哦..如果您只期望一件商品,也应该使用 Single

public Single<Data> getData() {
        return Single.create(singleSubscriber -> {
            Data result = object.getData();
            if(result == null){
                singleSubscriber.onError(new Exception("no data"));
            } else {
                singleSubscriber.onSuccess(result);
            }
        });
    }

getData().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(data -> {
                //do something with your data
            }, error -> {
                //do something on error
            });

答案 1 :(得分:6)

您正在寻找Completable.create

  

Completable :表示延迟计算,没有任何值,只表示完成或异常。该类遵循与Reactive-Streams类似的事件模式:onSubscribe(onError | onComplete)?

Completable.create(subscriber -> {
    object.getData(new OnResponseListener() {
        @Override
        public void onSuccess() {
           subscriber.onCompleted();
        }

        @Override
        public void onError() {
           subscriber.onError(* put appropriate Throwable here *);
        }
    }
})
...//apply Schedulers
.subscribe((() -> *success*), (throwable -> *error*));

答案 2 :(得分:4)

我将如何重构您的代码;除了getData方法之外,我还将getData方法包装为Single:

public void getData( final OnResponseListener listener ){
    if(data!=null && !data.isEmpty()){
        listener.onSuccess();
    }
    else{
        listener.onError();
    }
}

public Single<Boolean> getDataSingle() {
    return Single.create(new SingleOnSubscribe<Boolean>() {
        @Override
        public void subscribe(SingleEmitter<Boolean> e) throws Exception {
            getData(new OnResponseListener() {
                @Override
                public void onSuccess() {
                    e.onSuccess(true);
                }

                @Override
                public void onError() {
                    e.onSuccess(false);
                }
            });
        }
    });
}

或者使用Java 8:

public Single<Boolean> getDataSingle() {
    return Single.create(e -> getData(
            new OnResponseListener() {
                @Override
                public void onSuccess() {
                    e.onSuccess(true);
                }

                @Override
                public void onError() {
                    e.onSuccess(false);
                }
            })
    );
}

现在你已经在回调的旁边暴露了一个Rx API。假设它是你自己的某种DataProvider,你现在可以在不处理回调的情况下使用它,如下所示:

dataProvider.getDataSingle()
        .map(result -> result ? "User exist" : "User doesn't exist")
        .subscribe(message -> display(message));

我使用Rx2但是使用Rx1逻辑是相同的。

我还使用了Single而不是Observable,因为您只等待一个值。兴趣是你的功能更具表现力的合同。

您不能代表Observable发出值,即调用类似myObservable.send(value)的内容。第一种解决方案是使用Subject。另一个解决方案(上面的解决方案)是使用Observable.create()(或Single.create())创建observable。你调用回调方法并在方法Observable.create()中创建监听器,因为它在Observable.create()内部,你可以调用onSuccess()方法,该方法告诉Observable传递一个值。

这是我用来将回调包装成observable的东西。起初有点复杂,但很容易适应。

我问你另一个例子。假设您想要将EditText的更改显示为Snackbar:

View rootView;
EditText editTextView;

//Wrap Android addTextChangedListener into an Observable
Observable<String> textObservable = Observable.create(consumer ->
        editTextView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                consumer.onNext(s.toString());
            }
        })
);

//Use it
textObservable.subscribe(text -> Snackbar.make(rootView, text, Snackbar.LENGTH_SHORT).show());

答案 3 :(得分:0)

Maybe.<String>create(new MaybeOnSubscribe<String>() {
      @Override
      public void subscribe(MaybeEmitter<String> e) throws Exception {
        OnSuccessListener(uri->{
          e.onSuccess(uri));
        })
        .addOnFailureListener(throwable -> {
          e.onError(throwable);
        });
      }
    });