RxJava2的各种恩怨情仇

来源:互联网 发布:golang 事件总线 编辑:程序博客网 时间:2024/05/01 07:43

本人写博客不擅长在开头阐述各种问题的由来,文笔不好阐述不清楚,所以直接上代码说事:

首先rxjava2比1来讲还是有很多不同的地方,先来讲讲大家倒背如流的flowable背压式减缓发射与接受效率不对等会出现的MissingBackpressureException异常,


同线程的情况下:

总结来说不切换线程必须要给上游一个处理事件的大小,利用 request(Long.MAX_VALUE)可以设置这个事件的大小,如果不设置这个大小同时又在相同的线程里,获取到的处理事件的大小为0,这样系统就会默认下游没有处理时间的能力,从而事件一直堆放最终导致内存溢出的问题,但是友好的是rxjava2中的观察者的实现类ResourceSubscriber已经在onstart中做了处理,源码如下:(记住一点:给出的事件处理一次会减少一个,意思就是处理的事件并不是你给出多少他就每次取多少,而是你给出十个事件,第一次取十个,第二次取九个,这样递减,一直到递减为0的时候表示下游没有处理能力,这样照样会出现内存溢出的问题)

/** * Called once the upstream sets a Subscription on this AsyncObserver. * * <p>You can perform initialization at this moment. The default * implementation requests Long.MAX_VALUE from upstream. */protected void onStart() {    request(Long.MAX_VALUE);}
所以可以放心的集成这个类来使用,


不同线程的情况下:

在不同线程的情况下,简要来说就是在rxjava中调用了线程调度器来来实现不同线程的情况下,下游不强制要求要给事件处理的大小,因为在每一个线程只能在当先线程中获取到处理事件的大小,因为前面将的是相同的线程的情况下必须设置,因为在相同的线程中获取到的跟你设置的是在同线程的情况下,所以在异步线程中上游获取到的处理事件的大小是上游的线程,根本拿不到下游线程的处理事件的大小,所以没有强制要求,简便来说就是上游获取到的处理事件的大小是0,因为你没有设置上游线程的大小,但是有个奇怪的问题,它没有出现内存溢出的问题,这是为什么呢?

其实很简单,观察者与被观察者中间加了一个缓冲区,而且这个缓冲区的大小是128kb,不要问我为什么知道,自己钻博客钻底层,下游处理的速度慢的话上游发射过快的事件会存入这个缓冲区,等下游处理完了事件后再来取。跟同线程一样,处理事件大小是递减的,按照原理应该是递减到0的时候会出现内存溢出的情况,但是为什么又没有呢?其实还是很简单的,因为下游一直处理事件当处理到一个时间段的时候会提醒上游我这边又可以处理128个了,上游又置处理事件的大小为128,这样依次循环所以才不会出现内存溢出的情况,(注:下游处理到96的时候通知上边置为128)


区别:

subscribe订阅在rxjava2中是没有返回值的,返回值为void (除了构建参数为consumer的subscribe),构建参数为consumer的都是包装类与rxjava1一样,不需要实现全部的方法,i你关心什么方法就实现什么包装类,真正的subscribe只有两个,一个是参数为Subscriber的 一个是FlowableSubscriber,前者没什么区别,后者的被观察者必须是背压式对象,例如Flowable<Message> ,因为没有返回值,所以要在onSubscribe中去解除引用对象 (注:ResourceSubscriber是FlowableSubscriber的子类)

public void test(String json) {  mRetrofitHelper.mSiteApi.setAllCancelTakeSite(json)      .compose(RxUtil.rxSchedulerHelper())      .subscribe(new FlowableSubscriber<Message>() {        @Override public void onSubscribe(Subscription s) {            s.cancel();        }        @Override public void onNext(Message message) {        }        @Override public void onError(Throwable t) {        }        @Override public void onComplete() {        }      });}
 

rxjava2中引入新的订阅subscribeWith,你传入什么他就返回什么,但是一般都是传入ResourceSubscriber的子类或者它本身,因为这个类是实现了Disposable和FlowableSubscriber的,可以实现背压式的处理,同时返回一个Disposable对象来解除他的引用防止内存泄漏,总之一句话,订阅的时候要传入的参数是背压式的 那么反射源必须是背压式处理的。


未完待续

原创粉丝点击