RxJava Observable、Single、Completable 、Maybe、Subject demo及其简单分析。

/*Reactive:
Rx是一个函数库,让开发者可以利用可观察序列和LINQ风格查询操作符来编写异步和基于事件的程序,使用Rx,开发者可以使用Observables表示异步数据流,用LINQ操作符查询异步数据流,用Schedulers参数化异步数据流的并发处理,Rx可以这样定义:Rx = Observables + LINQ + Schedulers
ReactiveX 给的定义是:Rx是一个使用可观察数据流进行异步编程的编程接口ReactiveX结合了观察者模式、迭代器模式和函数式编程的精华。

*/

   
/*

Observable是异步的双向push,Iterable是同步的单向push

在RxJava 2.x版本中,Observable和Flowable都是用来发射数据流的,但是我们在实际应用中,很多时候需要发射的数据并不是数据流的形式,而只是一条单一的数据,或者是一条完成通知,或者是一条错误通知。在这种情况下,如果使用Observable或者Flowable就显得有点大材小用,于是,为了满足这种单一数据或者通着的使用场景,变出现了Single.Completable.Maybe,接下来就针对这些类型做分析说明。

Single:只发射一条单一的数据,或者条异常通知不能发射完成通知,其中数据与通知只能二选一发射。

*/
@Test
    public void testSingle1() {
        
        Single.create(new SingleOnSubscribe<Integer>() {

            public void subscribe(SingleEmitter<Integer> emitter) throws Exception {
                emitter.onSuccess(0);
            }
        }).subscribe(new SingleObserver<Integer>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onSuccess(Integer t) {
                System.out.println("success, value is: " + t);
            }

            public void onError(Throwable e) {
                System.out.println("exception occured, caused by: " + e.getCause());
            }
        });
        
    }
    
    @Test
    public void testSingle2() {
        Single.create(new SingleOnSubscribe<Integer>() {

            public void subscribe(SingleEmitter<Integer> emitter) throws Exception {
                emitter.onError(new RuntimeException("Exception occured....."));
            }
        }).subscribe(new SingleObserver<Integer>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onSuccess(Integer t) {
                
            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }
        });
    }


    /*  
     Completable: 只发射一条完成通知或者发射一条异常通知,不能发射数据
    */
         // Completable 发射完成通知
    @Test
    public void testCompletable1() {
        Completable.create(new CompletableOnSubscribe() {
            public void subscribe(CompletableEmitter emitter) throws Exception {
                emitter.onComplete();
            }
        }).subscribe(new CompletableObserver() {

            public void onSubscribe(Disposable d) {

            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }

            public void onComplete() {
                System.out.println("excute finished....");
            }
        });
    }

    // Completable 发射异常通知
    @Test
    public void testCompletable2() {
        Completable.create(new CompletableOnSubscribe() {

            public void subscribe(CompletableEmitter emitter) throws Exception {
                emitter.onError(new RuntimeException("Exception......."));
            }
        }).subscribe(new CompletableObserver() {

            public void onSubscribe(Disposable d) {

            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }
            
            public void onComplete() {
                System.out.println("执行完成");
            }
        });
    }


    /* 
        Maybe:可以发射一条单一的数据以及一条异常通知或者一条完成通知,需要注意的是,异常通知和完成通知只能选择其中一个,发射数据只能知完成通知或者异常通知之前,否则发送数据无效
    
    */
    @Test
        public void testMaybe() {
            Maybe.create(new MaybeOnSubscribe<Integer>() {

                public void subscribe(MaybeEmitter<Integer> emitter) throws Exception {
                    emitter.onSuccess(100);
                    emitter.onComplete();
                    emitter.onError(new RuntimeException("执行出异常。。。。。。"));
                }
            }).subscribe(new MaybeObserver<Integer>() {

                public void onSubscribe(Disposable d) {
                    
                }

                public void onSuccess(Integer value) {
                    System.out.println("excute successed,value is :" + value);
                }

                public void onError(Throwable e) {
                    e.printStackTrace();
                }

                public void onComplete() {
                    System.out.println("completed, well done!");
                }
            });
        }


    /*    
        Subject: Subject可以看成是一座桥梁或者代理,在某些RxJava中,它同时充当了Observer和Observable的角色,
        当它扮演Observer时候,他可以订阅一个或者多个Observable;当它扮演Observable的时候,它可以转发他收到(Observer)的数据,也可以发射新的数据。
        由于一个Subject订阅一个Observable,它可以触发这个Observable开始发射数据(如果那个Observable是"冷"的---即它等待有订阅才开始发射数据),
        因此有这样的效果,Subject可以把原来那个"冷"的Observable变成"热"的

        AsyncSubject:Observer会接收AsyncSubject的``onComplete()`之前的最后一个数据,如果因异常而终止,AsyncSubject将不会释放任何数据,但是会向Observer传递一个异常通知。
        示例代码如下:

    */

    @Test
    public void testSubject() { 
        AsyncSubject<String> as = AsyncSubject.create();
        as.onNext("onNext-Value1");
        as.onNext("onNext-Value2");
        as.onNext("onNext-Value3");
        as.onComplete();
        // as.onError(new RuntimeException("执行产生异常了......"));
        as.subscribe(new Observer<String>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onNext(String str) {
                System.out.println("onNext, value is: " + str);
            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }

            public void onComplete() {
                System.out.println("completed......");
            }
        });
        
    }

    /*
        上面的AsyncSubject 的执行结果如下:
        情形一:将 as.onError(new RuntimeException("执行产生异常了......")) 注释结果如下:
        onNext, value is: onNext-Value3
        completed......

        情形二:正常执行 as.onError(new RuntimeException("执行产生异常了......")) 结果如下:

    io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行产生异常了......
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.subjects.AsyncSubject.onError(AsyncSubject.java:168)
        at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject(RxJavaTest2.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
    Caused by: java.lang.RuntimeException: 执行产生异常了......
        ... 24 more
    Exception in thread "main" io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行产生异常了......
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.subjects.AsyncSubject.onError(AsyncSubject.java:168)
        at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject(RxJavaTest2.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
    Caused by: java.lang.RuntimeException: 执行产生异常了......
        ... 24 more
    onNext, value is: onNext-Value3
    completed......

    可以看出是先打印异常信息,然后是打印正常执行之后的结果

    */


    /*
        BehaviorSubject:Observer会接收到BehaviorSubject被订阅之前的最后一个数据,再接收其他发射过来的数据,
        如果BehaviorSubject被订阅之前没有发送任何数据则会发送一个默认数据
        BehaviorSubject和AsyncSubject的区别是:
         --AsyncSubject需要手动调用onComplete,并且在接收到onComplete前发送的最后一个数据之后不会再接收其他数据,
         --BehaviorSubject不需要手动调用onComplete(),它的Observer接收到的是BehaviorSubject被订阅之前发送的最后一个数据,且之后还会继续接收数据
         代码示例如下:
    */
    @Test
    public void testSubject2() {
        BehaviorSubject<String> behaviorSubject  = BehaviorSubject.createDefault("default");
//            behaviorSubject.onNext("behaviorSubject--1");
//            behaviorSubject.onNext("behaviorSubject--2");
//            behaviorSubject.onNext("behaviorSubject--3");
//            behaviorSubject.onComplete();
//            behaviorSubject.onError(new RuntimeException("执行发生异常..."));

        behaviorSubject.subscribe(new Observer<String>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onNext(String t) {
                System.out.println("value is: " + t);
            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }

            public void onComplete() {
                System.out.println("excute finished...");
            }});
        
        behaviorSubject.onNext("behaviorSubject--4");
        behaviorSubject.onNext("behaviorSubject--5");
        behaviorSubject.onNext("behaviorSubject--6");

    

    /*
        执行结果分析:
        情形一:在执行behaviorSubject.subscribe(...)之前不发送 behaviorbjectSu--1,behaviorbjectSu--2, behaviorbjectSu--3
        即注释如下代码:
        //    behaviorSubject.onNext("behaviorbjectSu--1");
        //    behaviorSubject.onNext("behaviorSubject--2");
        //    behaviorSubject.onNext("behaviorSubject--3");
        执行结果如下:
        value is: default
        value is: behaviorSubject--4
        value is: behaviorSubject--5
        value is: behaviorSubject--6

        情形二:正常发送 behaviorbjectSu--1,behaviorbjectSu--2, behaviorbjectSu--3
        执行结果如下:
        value is: behaviorSubject--3
        value is: behaviorSubject--4
        value is: behaviorSubject--5
        value is: behaviorSubject--6

        情形三:如果加上 behaviorSubject.onComplete();
        则执行结果只发送完成通知,如下所示:
        excute finished...

        情形四:加上 behaviorSubject.onError(new RuntimeException("执行发生异常...")); 
        则执行结果会打印异常信息,并发送完成通知,结果如下:

        io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行发生异常...
            at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
            at io.reactivex.subjects.BehaviorSubject.onError(BehaviorSubject.java:276)
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject2(RxJavaTest2.java:82)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
        Caused by: java.lang.RuntimeException: 执行发生异常...
            ... 24 more
        Exception in thread "main" io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行发生异常...
            at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
            at io.reactivex.subjects.BehaviorSubject.onError(BehaviorSubject.java:276)
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject2(RxJavaTest2.java:82)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
        Caused by: java.lang.RuntimeException: 执行发生异常...
            ... 24 more
        excute finished...


    */

    /*
        PublishSubject比较容易理解,相对比其他Subject常用,它的Observer只会接收到PublishSubject被订阅之后发送的数据。示例代码如下:    
    */

    @Test
    public void testSubject3() {
        
        PublishSubject<String> publishSubject = PublishSubject.create();
        
        publishSubject.onNext("publishSubject--1");
        publishSubject.onNext("publishSubject--2");
        publishSubject.onNext("publishSubject--3");
//        publishSubject.onError(new RuntimeException("执行发生异常了..."));
        publishSubject.onComplete();        
        publishSubject.subscribe(new Observer<String>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onNext(String t) {
                System.out.println("value is:" + t);
            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }

            public void onComplete() {
                System.out.println("excute finished...");
            }});
        
        publishSubject.onNext("publishSubject--4");
        publishSubject.onNext("publishSubject--5");
        publishSubject.onNext("publishSubject--6");
    }

    /*
        执行结果分析:
        情形一:
        正常执行(不发送完成通知(不需要),不发送异常通知) 结果如下:
        value is:publishSubject--4
        value is:publishSubject--5
        value is:publishSubject--

        情形二:
        添加完成通知(画蛇添足),结果将只返回完成通知,如下所示:
        excute finished...

        情形三:
        添加发射异常通知
        只打印异常信息,执行结果如下:

        java.lang.RuntimeException: 执行发生异常了...
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject3(RxJavaTest2.java:117)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

    */

    /*
        ReplaySubject:ReplaySubject会发射所有数据给观察者,无论它们是何时订阅的。也有多种版本的ReplaySubject,
        在重放缓存增长到一定大小的时候或过了一段时间后会丢弃旧的数据,示例代码如下:
    */
    @Test
    public void testSubject4() {
        /**
         * 创建默认初始容量大小为16的ReplaySubject,当数据条目超过16会重新分配内存空间,使用这种方式,不论ReplaySubject何时被订阅,Observer都能接收到数据,源码如下:
         * 
         * @CheckReturnValue
         * @NonNull 
         * public static <T> ReplaySubject<T> create() { 
         *         return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(16)); 
         * }
         **/
        ReplaySubject<String> replaySubject = ReplaySubject.create();
        
        replaySubject.onNext("replaySubject--1");
        replaySubject.onNext("replaySubject--2");
        replaySubject.onNext("replaySubject--3");
    //        replaySubject.onComplete();

        replaySubject.subscribe(new Observer<String>() {

            public void onSubscribe(Disposable d) {
                
            }

            public void onNext(String t) {
                System.out.println("value is: " + t);
            }

            public void onError(Throwable e) {
                e.printStackTrace();
            }

            public void onComplete() {
                System.out.println("excute finished...");
            }
        });
        
        replaySubject.onNext("replaySubject--4");
        replaySubject.onNext("replaySubject--5");
        replaySubject.onNext("replaySubject--6");
        replaySubject.onError(new RuntimeException("执行出现异常..."));


        /**
         * 也可以创建指定初始容量大小的ReplaySubject,初始容量值即为 capacityHint的大小,源码如下:
         * @CheckReturnValue
         * @NonNull 
         * public static <T> ReplaySubject<T> create(int capacityHint) { 
         *         return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(capacityHint)); 
         * }
         **/
        // 创建一个初始大小为60的ReplaySubject
        // replaySubject = ReplaySubject.create(60);

        /**
         * 还可以创建只缓存在订阅前最后发送的指定数量的 ReplaySubject,源码如下所示
         * 
         * @CheckReturnValue
         * @NonNull 
         * public static <T> ReplaySubject<T> createWithSize(int maxSize) {
         *      return new ReplaySubject<T>(new SizeBoundReplayBuffer<T>(maxSize));
         * }
         **/

        //只缓存订阅前最后发送的3条数据
        // replaySubject = ReplaySubject.createWithSize(3);

        /**
         * 还可以创建在被订阅前限时发送的ReplaySubject,源码如下:
         *  @CheckReturnValue
         *    @NonNull
               *    public static <T> ReplaySubject<T> createWithTime(long maxAge, TimeUnit unit, Scheduler scheduler) {
         *        return new ReplaySubject<T>(new SizeAndTimeBoundReplayBuffer<T>(Integer.MAX_VALUE, maxAge, unit, scheduler));
         *    }
         * 
         **/
        // replaySubject被订阅前的前2秒内发送的数据才能被接收
        // replaySubject=ReplaySubject.createWithTime(2,TimeUnit.SECONDS,Schedulers.computation());
        
        

    }

    /*
        执行结果分析:
        情形一:
        当在订阅之后再发送异常通知的话,前面的执行只要没有碰到完成通知,前面发送的通知都不受影响,通知会正常执行,并在最后打印异常通知的信息,执行结果如下:
        value is: replaySubject--1
        value is: replaySubject--2
        value is: replaySubject--3
        value is: replaySubject--4
        value is: replaySubject--5
        value is: replaySubject--6
        java.lang.RuntimeException: 执行出现异常...
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject4(RxJavaTest2.java:184)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

        情形二:若果在订阅之前就发射完成通知,那么订阅之后发射的数据将失效,除了异常通知。执行结果如下:

        value is: replaySubject--1
        value is: replaySubject--2
        value is: replaySubject--3
        excute finished...
        io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行出现异常...
            at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
            at io.reactivex.subjects.ReplaySubject.onError(ReplaySubject.java:360)
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject4(RxJavaTest2.java:184)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
        Caused by: java.lang.RuntimeException: 执行出现异常...
            ... 24 more
        Exception in thread "main" io.reactivex.exceptions.UndeliverableException: java.lang.RuntimeException: 执行出现异常...
            at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
            at io.reactivex.subjects.ReplaySubject.onError(ReplaySubject.java:360)
            at com.rxjava.program.rxjava_program.RxJavaTest2.testSubject4(RxJavaTest2.java:184)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
        Caused by: java.lang.RuntimeException: 执行出现异常...
            ... 24 more


    */
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值