使用RxJava代替接口回调(Android)

3
我是一名有用的助手,可以翻译文本。
新手使用RxJava,对于接口回调(通过接口变量从代码内部/模块调用)和RxJava有疑问。 为了更清晰,举个例子: 标准回调接口实现,接口、A类和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"时,结果为:"回调调用了方法somethingHappened"。可以从classB中调用接口的方法onCallbackCalled(String str) 任意次
类A ↓ ............................................ 通过构造函数注入接口
类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);
    }
}

Scheme是:
CLASS A ↓........................ 一次调用获取Observable资源
CLASS B................↑ EDIT 返回一个可发出0到n个值的observable 所以基本上你从顶层(在这个例子中)调用并得到内部层状态的响应。
问题:
1)假设您有一个正在动态更改(但不是任何类型的AsyncTask等)的模型(内部层),并且您想通知顶层(例如UI)状态已更改(很好的例子:游戏),该怎么做?
2)RxJava库中是否有任何类型的“桥接”类(我认为它是“订阅它,然后您可以多次传递参数给它,并且信息/observable将被发出到订阅者”)?
3)在尝试这样做而不是标准接口回调(在上述情况下,而不是“点击按钮,仅获取一次响应”)的情况下,是否有意义和优势?
更新,基于上述示例的答案
正如Bob Dalgleish所提到的那样,制作这样的桥梁的方法是使用扩展Subject<T> 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;
    }
}

下降趋势可能是,如果我们想要使用一个“桥接器”来处理多个回调类型(接口具有方法,我们仅使用一个方法:“onNext()”),我们可能需要创建带有回调参数的包装类。 在我看来,这不是大问题。
另一方面,我们可以访问所有RxJava运算符。 http://reactivex.io/documentation/operators.html (上面的示例适用于RxJava2,在其中Disposable基本上是RxJava1中的Subscription)。

你需要阅读RxJava文档。互联网上也有许多教程。你需要帮忙找一个好的教程吗? - Bob Dalgleish
不,我没有。谢谢。我不确定你是否在嘲笑,但问题是合法的。如果我可以通过简单地输入“如何回调RxJava”来找到答案,我就不会在这里提问了;)。我找到了一个解决“问题”的方法(仍然不确定是否值得这样做),并且可以使用RxJava库中的BehaviorSubject<>类来实现上述目标(同时是Observable和Observer的对象)。我会在空闲时间更新并添加答案。干杯。 - Gregory Iwanek
我不是很确定你在问什么。我会尝试在下面回答。而且,不,我没有嘲笑。 - Bob Dalgleish
这个问题对我来说有点难理解。我想这是因为我不太了解RxJava,我只知道接口回调。 - Harsha
1个回答

0

需要注意的第一件事是:

CLASS B................↑ 返回 0 到 n 个可观察对象给观察者

这并不正确。B 类返回一个可观察对象,它偶尔会发出 0 到 n 个值。

  1. (问题不太清楚)。来自类 B 的内部可观测对象由于某种原因正在改变状态。最常见的原因是另一个进程/任务/线程正在输入数据,并且您希望在 UI 中显示结果状态。

  2. 我经常使用的一种简单类型的“桥接”类是几个 Subject<> 类之一。您可以使用 .onNext() 向它们发出新值,订阅者将收到这些值。

  3. 如果回调接口都被标准化了,那么它们将具有一定优势,但它们的变化非常大。您必须记住,您需要为此事物使用某个特定接口,而为另一件事情使用不同的接口。虽然现在 UI 事件往往相当统一,但尝试混合 UI 事件、网络事件和数据库事件仍将使您感到不知所措。拥有一个更小的接口类别,大多数封装在 rxJava 通用类中,使组合功能变得更容易。

编辑:改进示例代码。

有一篇来自Yammer Engineering的好文章介绍了如何使用Observable.create()(之前是Observable.fromEmitter(),之前是Observable.fromAsync())。他提到的重要点包括:

  1. 使用Observable.create()会通过向底层接口注册侦听器来处理订阅步骤。更重要的是,当发生unsubscribe()时,它会安排取消注册侦听器。

  2. 默认情况下,此代码可以处理多个订阅者,每个订阅者都会收到自己的可观测数据流。

  3. 正如我上面提到的,侦听器协议特定于您注册的内容。如果该内容仅支持单个侦听器,则可能需要引入一个Subject以订阅观察的内容,并且所有其他观察者都订阅该Subject

编辑结束。

我最喜欢的解决方案组合示例是distinctUntilChanged()操作符。因为它是适用于泛型Observable的运算符,所以封装了保存连续值进行比较并仅发出不同值的有状态属性。我经常用它来记录状态变化。要使用标准回调接口实现相同的目的,需要为每个现有接口添加一个不同的接口来保存先前的值。
所以,是的,在大多数情况下,使用rxJava的可观察对象方法是值得的,仅仅是为了不必记住哪些众多的回调协议在当前情况下适用。

好的。谢谢。 我回答了一个问题。 - Gregory Iwanek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接