RxJava 而不是接口回调(Android)
RxJava instead of interface callbacks ( Android)
RxJava 的新手,我对接口回调(通过接口变量从代码的内部 layer/module 调用)与 RxJava 有疑问。
为了更清楚,快速示例:
标准回调接口实现,接口,classA和B
interface CustomCallback {
void onCallbackCalled(String str);
}
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB(new CustomCallback() {
@Override
public void onCallbackCalled(String str) {
System.out.println("Callback called " + str);
}
});
}
}
class ClassB {
private CustomCallback customCallback;
public ClassB(CustomCallback callback) {
customCallback = callback;
}
private void somethingHappened() {
customCallback.onCallbackCalled("method somethingHappened");
}
}
当调用classB方法"somethingHappened"时,结果为:"Callback called method somethingHappened"。
接口的方法 onCallbackCalled(String str) 可以从 classB 调用任意多次 .
CLASS一个↓................................................ ......通过构造函数注入接口
CLASS B................↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ onCallbackCalled(...) 0... n个
现在是 RxJava。我发现的 99% 的案例。
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB();
}
public void rxJavaMethod() {
DisposableObserver<String> observer = classB.getObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<String>() {
@Override
public void onNext(String s) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
}
class ClassB {
private Observable<String> getObservable() {
return Observable.just(can be different from "just", for sake of example);
}
}
方案是:
CLASS A ↓................................ 一次获取Observable资源的调用
CLASS B................↑ EDIT returns observable 发射 0.. .n 值
所以基本上你从顶层调用(在这个例子中),你从内层得到关于状态的响应。
问题:
1) 如果你有一个动态变化的模型(内层)(但不是任何类型的 AsyncTask 等),并且你想通知顶层(例如 UI)该状态已更改(很好的例子:游戏)。
2) RxJava 库中是否有任何类型的 "bridge" class (我认为它是“订阅它,然后你可以向它传递任意多次参数,并且information/observable 将发送给订阅者。
3) 尝试这样做而不是标准接口回调是否有任何意义和优势(在上述情况下,不是“单击按钮,获得一次响应”)
更新,基于上述示例的答案
正如 Bob Dalgleish 提到的,建立这种桥梁的方法是使用 class 扩展 Subject rxjava 之一。
http://reactivex.io/documentation/subject.html
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB();
}
public void rxJavaMethod() {
DisposableObserver<String> observer = classB.getCallbackSubjectRx()
.subscribeWith(new DisposableObserver<String>() {
@Override
public void onNext(String s) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
}
class ClassB {
private BehaviorSubject<String> mCallbackRx;
public ClassB() {
mCallbackRx = BehaviorSubject.create();
}
// method somethingHappened can be invoked whenever whe want and
// it will send given parameter to all subscribers
private void somethingHappened() {
mCallbackRx.onNext("method somethingHappened");
}
// multiple subscribers allowed
public BehaviorSubject<String> getCallbackSubjectRx() {
return mCallbackRx;
}
}
缺点可能是,如果我们想使用一个 "bridge" 来处理多个回调类型(接口有方法,我们只使用一个方法:"onNext()"),我们可能需要创建包装器class 带回调参数。在我看来这不是什么大问题。
另一方面,我们可以访问所有 RxJava 运算符。
http://reactivex.io/documentation/operators.html
(上面的示例是针对 RxJava2 的,其中 Disposable 基本上是从 RxJava1 订阅)。
首先要注意的是
CLASS B................↑ returns 0...n observables to observer
不正确。 Class B returns 一个 observable,它偶尔会发出 0..n 个值。
(问题不清楚)。来自 class B 的内部 observable,无论出于何种原因正在改变状态。最常见的原因是另一个 process/task/thread 正在喂它,而您想在 UI.
中显示结果状态
一种简单的 "bridging" class 类型,我一直在使用几个 Subject<>
class 中的任何一个。您可以使用 .onNext()
向他们发送新值,订阅者将获得这些值。
如果回调接口都标准化了,那倒是有一些优势,但是各地都不一样。您必须记住,对于您正在查看的这个东西,您需要一些特定的界面,而对于另一个东西,则需要一个不同的界面。虽然现在 UI 事件趋于统一,但尝试将 UI 事件与网络事件和数据库事件混合使用仍然会让您感到不知所措。具有更小的 class 接口,大部分封装在 rxJava 泛型 classes 中,使得组合功能更容易。
编辑:改进示例代码。
Yammer Engineering 有一篇关于使用 Observable.create()
的好文章(以前是 Observable.fromEmitter()
,以前是 Observable.fromAsync()
。他提出的要点是
使用 Observable.create()
通过向底层接口注册侦听器来为您处理订阅步骤。更重要的是,它安排在 unsubscribe()
发生时注销侦听器。
开箱即用,此代码处理多个订阅者,每个订阅者接收其自己的可观察数据流。
正如我上面提到的,侦听器协议特定于您注册的对象。如果该事物仅支持单个侦听器,那么您可能希望引入一个订阅被观察事物的 Subject
,而所有其他观察者都订阅该主题。
编辑结束。
我最喜欢的解组合示例是 distinctUntilChanged()
运算符。因为它是一个适用于通用可观察对象的运算符,所以它封装了有状态 属性 保存连续值以进行比较并且只发出不同的值。我经常用它来记录状态变化。要使用标准回调接口达到相同的目的,需要添加一个不同的接口来将先前的值保存到每个现有接口。
所以,是的,大多数时候值得使用 rxJava observables 方法,只是为了不必记住当前情况下可能适用的许多回调协议中的哪一个。
RxJava 的新手,我对接口回调(通过接口变量从代码的内部 layer/module 调用)与 RxJava 有疑问。 为了更清楚,快速示例:
标准回调接口实现,接口,classA和B
interface CustomCallback {
void onCallbackCalled(String str);
}
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB(new CustomCallback() {
@Override
public void onCallbackCalled(String str) {
System.out.println("Callback called " + str);
}
});
}
}
class ClassB {
private CustomCallback customCallback;
public ClassB(CustomCallback callback) {
customCallback = callback;
}
private void somethingHappened() {
customCallback.onCallbackCalled("method somethingHappened");
}
}
当调用classB方法"somethingHappened"时,结果为:"Callback called method somethingHappened"。 接口的方法 onCallbackCalled(String str) 可以从 classB 调用任意多次 .
CLASS一个↓................................................ ......通过构造函数注入接口
CLASS B................↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ onCallbackCalled(...) 0... n个
现在是 RxJava。我发现的 99% 的案例。
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB();
}
public void rxJavaMethod() {
DisposableObserver<String> observer = classB.getObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<String>() {
@Override
public void onNext(String s) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
}
class ClassB {
private Observable<String> getObservable() {
return Observable.just(can be different from "just", for sake of example);
}
}
方案是:
CLASS A ↓................................ 一次获取Observable资源的调用
CLASS B................↑ EDIT returns observable 发射 0.. .n 值
所以基本上你从顶层调用(在这个例子中),你从内层得到关于状态的响应。
问题:
1) 如果你有一个动态变化的模型(内层)(但不是任何类型的 AsyncTask 等),并且你想通知顶层(例如 UI)该状态已更改(很好的例子:游戏)。
2) RxJava 库中是否有任何类型的 "bridge" class (我认为它是“订阅它,然后你可以向它传递任意多次参数,并且information/observable 将发送给订阅者。
3) 尝试这样做而不是标准接口回调是否有任何意义和优势(在上述情况下,不是“单击按钮,获得一次响应”)
更新,基于上述示例的答案
正如 Bob Dalgleish 提到的,建立这种桥梁的方法是使用 class 扩展 Subject
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB();
}
public void rxJavaMethod() {
DisposableObserver<String> observer = classB.getCallbackSubjectRx()
.subscribeWith(new DisposableObserver<String>() {
@Override
public void onNext(String s) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
}
class ClassB {
private BehaviorSubject<String> mCallbackRx;
public ClassB() {
mCallbackRx = BehaviorSubject.create();
}
// method somethingHappened can be invoked whenever whe want and
// it will send given parameter to all subscribers
private void somethingHappened() {
mCallbackRx.onNext("method somethingHappened");
}
// multiple subscribers allowed
public BehaviorSubject<String> getCallbackSubjectRx() {
return mCallbackRx;
}
}
缺点可能是,如果我们想使用一个 "bridge" 来处理多个回调类型(接口有方法,我们只使用一个方法:"onNext()"),我们可能需要创建包装器class 带回调参数。在我看来这不是什么大问题。
另一方面,我们可以访问所有 RxJava 运算符。 http://reactivex.io/documentation/operators.html
(上面的示例是针对 RxJava2 的,其中 Disposable 基本上是从 RxJava1 订阅)。
首先要注意的是
CLASS B................↑ returns 0...n observables to observer
不正确。 Class B returns 一个 observable,它偶尔会发出 0..n 个值。
(问题不清楚)。来自 class B 的内部 observable,无论出于何种原因正在改变状态。最常见的原因是另一个 process/task/thread 正在喂它,而您想在 UI.
中显示结果状态
一种简单的 "bridging" class 类型,我一直在使用几个
Subject<>
class 中的任何一个。您可以使用.onNext()
向他们发送新值,订阅者将获得这些值。如果回调接口都标准化了,那倒是有一些优势,但是各地都不一样。您必须记住,对于您正在查看的这个东西,您需要一些特定的界面,而对于另一个东西,则需要一个不同的界面。虽然现在 UI 事件趋于统一,但尝试将 UI 事件与网络事件和数据库事件混合使用仍然会让您感到不知所措。具有更小的 class 接口,大部分封装在 rxJava 泛型 classes 中,使得组合功能更容易。
编辑:改进示例代码。
Yammer Engineering 有一篇关于使用 Observable.create()
的好文章(以前是 Observable.fromEmitter()
,以前是 Observable.fromAsync()
。他提出的要点是
使用
Observable.create()
通过向底层接口注册侦听器来为您处理订阅步骤。更重要的是,它安排在unsubscribe()
发生时注销侦听器。开箱即用,此代码处理多个订阅者,每个订阅者接收其自己的可观察数据流。
正如我上面提到的,侦听器协议特定于您注册的对象。如果该事物仅支持单个侦听器,那么您可能希望引入一个订阅被观察事物的
Subject
,而所有其他观察者都订阅该主题。
编辑结束。
我最喜欢的解组合示例是 distinctUntilChanged()
运算符。因为它是一个适用于通用可观察对象的运算符,所以它封装了有状态 属性 保存连续值以进行比较并且只发出不同的值。我经常用它来记录状态变化。要使用标准回调接口达到相同的目的,需要添加一个不同的接口来将先前的值保存到每个现有接口。
所以,是的,大多数时候值得使用 rxJava observables 方法,只是为了不必记住当前情况下可能适用的许多回调协议中的哪一个。