草庐IT

android - 在 RxJava2(Android) 中订阅与订阅?

coder 2023-06-05 原文

什么时候调用 subscribeWith 方法而不是简单的 subscribe ?用例是什么?

compositeDisposable.add(get()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(this::handleResponse, this::handleError));

VS
   compositeDisposable.add(get()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
              //  .subscribe(this::handleResponse, this::handleError);
                .subscribeWith(new DisposableObserver<News>() {
                    @Override public void onNext(News value) {
                        handleResponse(value);
                    }

                    @Override public void onError(Throwable e) {
                        handleError(e);
                    }

                    @Override public void onComplete() {
                       // dispose here ? why? when the whole thing will get disposed later
                       //via  compositeDisposable.dispose();  in onDestroy();
                    }
                }));

谢谢

稍后添加

根据文档,两者都返回一次性 SingleObserver 实例:
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <E extends SingleObserver<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(final Consumer<? super T> onSuccess, final Consumer<? super Throwable> onError) {
    ObjectHelper.requireNonNull(onSuccess, "onSuccess is null");
    ObjectHelper.requireNonNull(onError, "onError is null");
    ConsumerSingleObserver<T> s = new ConsumerSingleObserver<T>(onSuccess, onError);
    subscribe(s);
    return s;
}

其中 ConsumerSingleObserver 类实现了 SingleObserver 和 Disposable。

最佳答案

Observable#subscribe 解释:

在您的第一个代码 fragment 中:

.subscribe(this::handleResponse, this::handleError));



您实际上正在使用几个重载 Observable#subscribe 之一方法:
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError)

还有一个也接受了 Action在完成时执行:
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
        Action onComplete) {

另一个选项允许您简单地传入 Observer (注意:void 方法) (编辑 2 - 此方法在 ObservableSource 中定义,这是 Observable 扩展的接口(interface)。)
public final void subscribe(Observer<? super T> observer)

在您问题的第二个代码 fragment 中,您使用了 subscribeWith方法只返回 Observer您传入(为了方便/缓存等):
public final <E extends Observer<? super T>> E subscribeWith(E observer)

观察者#onComplete 解释:

Observer#onComplete 在 Observable 发出流中的所有项目后被调用。
从java文档:
/**
 * Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
 * <p>
 * The {@link Observable} will not call this method if it calls {@link #onError}.
 */
void onComplete();

例如,如果 get()在您的代码 fragment 中返回了 Observable发出多个 News对象,每一个都将在 Observer#onNext 中处理.您可以在此处处理每个项目。

在它们都被处理完(并假设没有发生错误)之后,onComplete会被调用。在这里您可以执行您需要做的任何额外操作(例如更新 UI),因为您知道您已经处理了所有 News对象。

这不要与 Disposable#dispose 混淆它在可观察流结束(完成/错误)时被调用,或者由您手动终止观察(这是 CompositeDisposable 的用武之地,因为它可以帮助您一次性处理所有的 Disposable s) .

如果在您的方案中 get()将返回 Observable只发出一个项目,而不是使用 Observable ,考虑使用 io.reactivex.Single您只处理一项(在 onSuccess 中),并且不需要指定 Action对于 onComplete :)

编辑 : 回复你的评论:

However I still do not get use of subscribeWith, you said it passes the observer for caching etc , where does it pass to? on complete? and from what I understood subscribeWith is not actually consuming the observable( or Single) right?



进一步澄清subscribeWith解释,我的意思是它消费 Observer您传递给 subscribeWith 的对象(与 subscribe 方法完全一样)但是它还会额外返回同一个 Observer 给你。在撰写本文时, subscribeWith 的实现是:
public final <E extends Observer<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

因此,subscribeWith 可以 可与 subscribe 互换使用.

Can you give a use case of subscribeWith with example? I guess that will answer the question completely


subscribeWith javadoc 给出了以下用法示例:
Observable<Integer> source = Observable.range(1, 10);
CompositeDisposable composite = new CompositeDisposable();

ResourceObserver<Integer> rs = new ResourceObserver<>() {
     // ...
};

composite.add(source.subscribeWith(rs));

看这里subscribeWith的用法将返回相同的 ResourceObserver实例化的对象。这为执行订阅和添加 ResourceObserver 提供了便利。到 CompositeDisposable在一行中(注意 ResourceObservable 实现了 Disposable 。)

编辑 2 回复第二条评论。

source.subscribeWith(rs); source.subscribe(rs); both return SingleObserver instance,


ObservableSource#subscribe(Observer <? super T> observer) 返回 Observer .它是一个 void 方法(参见上面 Observable#subscribe 解释下的注释。)而 Observable#subscribeWith 返回 Observer .
如果我们使用 ObservableSource#subscribe 重写示例使用代码相反,我们必须像这样在两行中完成它:
source.subscribe(rs); //ObservableSource#subscribe is a void method so nothing will be returned
composite.add(rs);

Observable#subscribeWith方法使我们可以方便地在一行中完成上述操作 composite.add(source.subscribeWith(rs));
它可能会与所有看起来有些相似的重载 subscribe 方法混淆,但是它们之间存在差异(其中一些是微妙的)。查看代码和文档有助于区分它们。

编辑 3 subscribeWith 的另一个示例用例
subscribeWith当您有 Observer 的特定实现时,方法很有用。您可能想要重用。比如上面的示例代码中,就提供了ResourceObserver的具体实现在订阅中,从而继承它的功能,同时仍然允许您处理 onNext onError 和 onComplete。

另一个示例用途:对于您问题中的示例代码,如果您想对 get() 执行相同的订阅怎么办?多处回应?

而不是复制 Consumer onNext 和 onError 跨不同类的实现,您可以做的是为例如定义一个新类。
//sample code..
public class GetNewsObserver extends DisposableObserver<News> {
    //implement your onNext, onError, onComplete.
    ....
}

现在,只要你这样做 get()请求,您只需执行以下操作即可订阅:
compositeDisposable.add(get()
    ...
    .subscribeWith(new GetNewsObserver()));

现在看代码很简单,你保持处理响应的责任分离,现在可以重用 GetNewsObserver哪里都行。

关于android - 在 RxJava2(Android) 中订阅与订阅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44640844/

有关android - 在 RxJava2(Android) 中订阅与订阅?的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. ruby-on-rails - 无法使用 Stripe 保存或取消订阅 - 2

    将stripe的API与RubyonRails结合使用我无法保存订阅。我能够检索、更新和保存客户对象:customer=Stripe::Customer.retrieve(some_customer_id)#thisworkscustomer.save#thisworks我还可以检索订阅:subscription=customer.subscriptions.retrieve("some_subscription_id")#这个有效但是,在尝试保存订阅时:subscription.save#这不起作用我不断得到这个:NoMethodError:undefinedmethod`save'

  3. ruby-on-rails - 在 Rails 中是否有比 Observers 更直接的方式来执行发布/订阅模式? - 2

    我有一个模型依赖于一个单独的、联合的模型。classMagazine图像是多态的,可以附加到许多对象(页面和文章),而不仅仅是杂志。杂志需要在相关图像发生任何变化时自行更新该杂志还保存了一张自己的截图,可用于宣传:classMagazine现在如果图像发生变化,杂志也需要更新其截图。所以杂志真的需要知道图片什么时候出了问题。所以我们可以天真地直接从封面图片触发屏幕截图更新classImage...但是图片不应该代表杂志做事然而,图片可以用于许多不同的对象,实际上不应该对杂志进行特定的操作,因为这不是图片的责任。该图像也可能附加到页面或文章,并且不需要为它们做各种事情。“正常”的rail

  4. ruby-on-rails - 在 ActionCable 中找不到订阅类 'MyChannel' - 2

    我在使用ActionCable时遇到问题,每当我运行我的程序时,我都会收到一条错误消息,提示SubscriptionClassnotfoundConversationChannel当我尝试发送消息时,我得到了这个日志SuccessfullyupgradedtoWebSocket(REQUEST_METHOD:GET,HTTP_CONNECTION:Upgrade,HTTP_UPGRADE:websocket)Subscriptionclassnotfound:"ConversationChannel"Couldnotexecutecommandfrom{"command"=>"mess

  5. ruby - AMQP 动态创建订阅队列 - 2

    我正在尝试使用AMQP、Websockets和Ruby构建一个简单的聊天应用程序。我知道这可能不是理解AMQP的最佳用例,但我想了解我哪里出错了。以下是我的amqp-server代码require'rubygems'require'amqp'require'mongo'require'em-websocket'require'json'classMessageParser#messageformat=>"room:harry_potter,nickname:siddharth,room:members"defself.parse(message)parsed_message=JSON.

  6. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  7. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

  8. ruby - 订阅一个队列,收到1条消息,然后取消订阅 - 2

    我有一个场景,我需要极快地分发和处理作业。我将在队列中快速填充大约45个作业,我可以同时处理大约20个(5台机器,每台机器4个内核)。每项工作花费的时间长短不一,而且垃圾收集使事情变得复杂,因此我需要能够让消费者离线以进行垃圾收集。目前,我的一切都与pop一起工作(每个消费者每5毫秒弹出一次)。这似乎是不可取的,因为它转换为每秒600个pop请求到rabbitmq。如果有一个类似于订阅的pop命令,但只针对一条消息,我会很高兴。(进程会阻塞,等待来自rabbitMQ连接的输入,通过类似于Kernel.select的东西)我试图欺骗AMQPgem做这样的事情,但它不起作用:我似乎无法取消

  9. AiBote 2022 新研发的自动化框架,支持 Android 和 Windows 系统。速度非常快 - 2

    Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可

  10. Android Gradle 7.1+新版本依赖变化 - 2

    前一段时间由于工作需要把可爱的小雪狐舍弃了,找到了小蜜蜂。但是新版本的小蜜蜂出现了很多和旧版本不一样的位置。1.功能位置迁移,原来在工程build.gradle的buildscript和allprojects移动至setting.gradle并改名为pluginManagement和dependencyResolutionManagement。里面的东西依旧可以按照原来的copy过来。pluginManagement{repositories{gradlePluginPortal()google()mavenCentral()}}dependencyResolutionManagement{r

随机推荐