我使用侦听器作为回调来观察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");
}
});
谢谢!
答案 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);
});
}
});