当前位置: 首页 > 知识库问答 >
问题:

RxJava而不是接口回调(Android)

仰欣悦
2023-03-14

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方法“SomethingOccessed”时,结果是:“回调调用了方法SomethingOccessed”。接口的方法onCallbackCalled(String str)可以从classB中调用任意多次。

类A↓..........................................通过构造函数注入接口

B类..................................................................................................................

现在是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);
    }
}

方案是:

A类↓........................ 一个关于获取可观测资源的呼吁

B类。。。。。。。。。。。。。。。。↑ EDIT返回发出0的可观测值。。。n个值

所以基本上,您从顶层(在本例中)调用,并从内层得到关于状态的响应。

问题:

1) 如果您有一个动态变化的模型(内层)(但不是任何类型的异步任务等),并且您希望通知顶层(例如UI)状态已更改(很好的示例:游戏),该怎么办。

2) RxJava库中是否有任何类型的“bridge”类(我认为它是“订阅它,然后您可以根据需要多次向它传递参数,并且信息/可观察信息将发送给订阅者”)。

3) 尝试这样做而不是标准接口回调(在上述情况下,不是“单击按钮,获取一次响应”)有什么意义和优势吗

更新,答案基于上述示例

正如鲍勃·达格利什(BobDalgleish)所提到的,建立这种桥梁的方法是使用一个类扩展主题

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订阅)。

共有1个答案

孟彦
2023-03-14

首先要注意的是

B类。。。。。。。。。。。。。。。。↑ 返回0。。。n观测值对观测值

不正确。B类返回一个可观察的,它偶尔会在其上发出0... n个值。

>

  • (问题不清楚)。来自B类的内部可观察物,无论出于何种原因,都在改变状态。最常见的原因是另一个进程/任务/线程正在向其提供数据,您希望在UI中显示结果状态。

    一种简单的“桥接”类,我一直在使用几个主题中的任何一个

    如果回调接口都是标准化的,那么它们会有一些优势,但各地的回调接口各不相同。您必须记住,对于您正在查看的对象,您需要一些特定的接口,对于另一个对象,您需要一个不同的接口。虽然现在UI事件趋于一致,但尝试将UI事件、网络事件和数据库事件混合使用仍然会让您感到不知所措。拥有一个小得多的接口类(主要封装在rxJava泛型类中),可以更轻松地组合功能

    编辑:改进示例代码。

    Yammer Engineering有一篇关于使用Observable.create()(原Observable.fromEmitter(),原Observable.fromAsync()的好文章

    >

  • 使用Observable.create()通过将侦听器注册到底层接口来为您处理订阅步骤。更重要的是,它安排在取消订阅()发生时取消注册侦听器。

    这段代码处理多个订阅者,每个订阅者都接收自己的可观察数据流。

    如上所述,侦听器协议对于您注册的对象是特定的。如果该事物只支持一个侦听器,那么您可能需要引入一个订阅被观察事物的主题,并且您的所有其他观察者都订阅该主题。

    编辑结束。

    我最喜欢的解决方案组合示例是distinctUntilChanged()操作符。因为它是一个处理泛型可观察对象的操作符,所以它封装了有状态属性,即保存连续值以进行比较,并且只发出不同的值。我经常使用它来记录状态更改。为了达到相同的目的,使用标准回调接口需要添加不同的接口,以便将先前的值保存到每个现有接口。

    因此,是的,大多数情况下,使用rxJava方法处理可观察对象是值得的,只是为了不必记住在当前情况下,许多回调协议中的哪一个可能适用。

  •  类似资料:
    • 我写了自己的类加载器,它与类一起工作,实现了接口插件。但是我不能将类转换为插件。怎么了? 错误:(18,47)java:不兼容的类型:java。lang.类无法转换为插件 我补充说,这是我的SimpleClassLoader类的主要部分,它扩展了ClassLoader。

    • 问题内容: 亲爱的开发人员, 我遇到了这个问题,对我来说似乎有点奇怪。看一下这段代码: 在其他包装上,我有以下代码: 运行时不接受提到的行,因为 “不能在fieldint.AddFilter的参数中使用fieldfilter(类型为 coreinterfaces.FieldFilter)作为类型为 coreinterfaces.FilterInterface:* coreinterfaces.Fi

    • 我在后端代码中使用了Spring数据jpa。我已经包含了实体,dto接口,服务和jpa存储库代码。 现在的问题是,当我在< code>TopicService中调用< code>getAllTopics()时。它返回< code>Topic对象的列表,而不是< code>TopicDto。< code>Topic对象包含一个< code >示例列表,我没有将它包含在< code>TopicDto中

    • 版本: 1.4.1 日期: 2021-01-14 当直播开始、结束和录制开始、结束、完成后,直播系统会通过用户在admin配置的回调信息以GET⽅式发起回调。若⽤户网站地址使⽤HTTPS协议进⾏数据安全传输时,⽤户需保证其拥有的CA证书是合法的。 ⽤户可以在admin后台指定的回调符合以下四种格式之⼀即为合法: 1、http://domain 2、http://domain?data=****(d

    • 问题内容: 在正确掌握接口最佳实践的过程中,我注意到一些声明,例如: 代替 -据我所知,原因是因为它有一定的灵活性,以防万一你不想实现ArrayList,但又可能实现另一种类型的列表。 通过这种逻辑,我建立了一个示例: 我的问题是,我无法访问batheSelf()方法,因为它仅适用于Cat。这使我相信,仅在使用接口中声明的方法时才应从接口声明(而不是子类中的其他方法),否则应直接从类中声明(在本例

    • 我有一个类扩展了另一个类(),并实现了一个接口(),如下所示: 接口类和父类都有函数,但我只想重写接口类。目前,这段代码会产生编译错误,因为父类()中的getMessage是。