Android :RxJava学习笔记之创建操作符

Posted JMW1407

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android :RxJava学习笔记之创建操作符相关的知识,希望对你有一定的参考价值。

创建操作符

1、creat

使用一个函数从头开始创建一个 Observable

我们可以使用 create 操作符从头开始创建一个 Observable 给这个操作符传递一个接受观察者作为参数的函数,编写这个函数让它的行为表现为一个 Observable ——恰当地调用观察者 onNext、onError、onComplete 方法。一个形式正确的有限 Observable 必须尝试调用观察者 onComplete() 一次或者它的 onError() 一次,而且此后不能再调用观察者的任何其他方法。

RxJava 建议我们在传递给 create 方法的函数时,先检查一下观察者的 isDisposed 状态,以便在没有观察者的时候,让我们的 Observable 停止发射数据,防止运行昂贵的运算。

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        try {
            if (!emitter.isDisposed()) {
                for (int i = 0; i < 5; i++) {
                    emitter.onNext(i);
                }
                emitter.onComplete();
            }
        } catch (Exception e) {
            emitter.onError(e);
        }
    }
}).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        Log.d(TAG, "Next-> " + integer);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Log.d(TAG, "Error-> " + throwable.getMessage());
    }
}, new Action() {
    @Override
    public void run() throws Exception {
        Log.d(TAG, "Complete.");
    }
});

执行结果

 Next-> 0
 Next-> 1
 Next-> 2
 Next-> 3
 Next-> 4
 Complete.

2、just

just 将单个数据转换为 发射这个单个数据的 Observable

Observable.just("Observable#just")
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "Next: " + s);
            }
        });

// 执行结果
 Next: Observable#just

just 类似于 from,但是 from 会将数组或 Iterable 的数据取出然后逐个发射,而 just 只是简单地原样发射,将数组或 Iterable 当作单个数据。

它可以接受一至十个参数,返回一个按参数列表顺序发射这些数据的 Observable

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.d(TAG, "Next: " + integer);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.d(TAG, "Error-> " + throwable.getMessage());
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "Complete.");
            }
        });

// 执行结果
 Next: 1
 Next: 2
 Next: 3
 Next: 4
 Next: 5
 Next: 6
 Next: 7
 Next: 8
 Next: 9
 Next: 10
 Complete.
List<String> s = Arrays.asList("Java", "android", "Ruby", "ios", "Swift");
    Observable
        .just(s)
        .subscribe(new Consumer<List<String>>() {
          @Override
          public void accept(List<String> strings) throws Exception {
            for (String str : strings) {
              System.out.println("accept: " + str);
            }
          }
        }, new Consumer<Throwable>() {
          @Override
          public void accept(Throwable throwable) throws Exception {
            System.out.println(throwable.getMessage());
          }
        });

输出结果

accept: Java
accept: Android
accept: Ruby
accept: Ios
accept: Swift

3、from

from 可以将其他种类的对象和数据类型转换为 Observable


当我们使用 Observable 时,如果要处理的数据都可以转换成 Observables ,而不是需要混合使用 Observables 和其他类型的数据,会非常方便。这让我们在数据流的整个生命周期中,可以使用一组统一的操作符来管理它们。

例如, Iterable 可以看成同步的 Observable; Future 可以看成总是只发射单个数据的 Observable。通过显式地将那些数据转换为 Observables ,我们可以像使用 Observable 样与它们交互。

因此,大部分 ReactiveX 实现都提供了将特定语言的对象和数据结构转换为 Observables 的方法。

RxJava 中, from 操作符可以将 Future、Iterable 和数组转换成 Obseruable 。对于 Iterable
和数组,产生的 Observable 会发射 Iterable 或数组的每一项数据。

fromArray

这个方法和 just() 类似,只不过 fromArray 可以传入多于10个的变量,并且可以传入一个数组。

Observable.fromArray("Observable", "fromArray")
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "Next: " + s);
            }
        });

// 执行结果
 Next: Observable
 Next: fromArray

fromIterable

直接发送一个 List 集合数据给观察者

List<Integer> items = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    items.add(i);
}

Observable.fromIterable(items)
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.d(TAG, "Next: " + integer);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.d(TAG, "Error-> " + throwable.getMessage());
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "Complete.");
            }
        });

// 执行结果
 Next: 0
 Next: 1
 Next: 2
 Next: 3
 Next: 4
 Complete.

fromFuture()

public static <T> Observable<T> fromFuture(Future<? extends T> future)

参数中的 Future 是 java.util.concurrent 中的 Future,Future 的作用是增加了 cancel() 等方法操作 Callable,它可以通过 get() 方法来获取 Callable 返回的值。

ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> future = executorService.submit(new MyCallable());

Observable.fromFuture(future)
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "Next: " + s);
            }
        });

private class MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Log.d(TAG, "模拟一些耗时的任务...");
        Thread.sleep(2000L);
        return "OK";
    }
}

// 执行结果
15:54:06.832  模拟一些耗时的任务...
15:54:08.833  Next: OK

fromFuture 方法有一个可接受两个可选参数的版本,分别指定超时时长和时间单位。如果过了指定的时长, Future 还没有返回一个值,那么这个 Observable 就会发射错误通知井终止。 下面的代码,把超时时间设置为 1s, Observable.fromFuture(future, 1, TimeUnit.SECONDS),执行结果如下:

16:00:44.260  模拟一些耗时的任务...
16:00:45.367  io.reactivex.exceptions.OnErrorNotImplementedException

4、defer、interval 和 timer

4.1 defer

直到有观察者订阅时才创建 Observable ,并且为每个观察者创建一个全新的 Observable

defer 操作符会一直等待直到有观察者订阅它,然后它使用 Observable 工厂方法生成一个 Observable。它对每个观察者都这样做,因此尽管每个订阅者都以为自己订阅的是同一个 Observable ,但事实上每个订阅者获取的是它们自己单独的数据序列。

在某些情况下,直到最后一分钟(订阅发生时)才生成 Observable ,以确保 Observable 包含最新的数据。

Observable<String> observable = Observable.defer(new Callable<ObservableSource<? extends String>>() {
    @Override
    public ObservableSource<? extends String> call() throws Exception {
        return Observable.just("hello, defer");
    }
});

observable.subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d(TAG, "Next: " + s);
    }
});

// 执行结果
 Next: hello, defer

4.2 interval

创建一个按固定时间间隔发射整数序列的 Observable

interval 操作符返回一个 Observable ,它按固定的时间间隔发射一个无限递增的整数序列。

interval 接受一个表示时间间隔的参数和一个表示时间单位的参数。 interval 默认在 computation 调度器上执行

Observable.interval(1, TimeUnit.SECONDS)
        .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Log.d(TAG, "Next: " + aLong);
            }
        });

// 执行结果
 Next: 0
 Next: 1
 Next: 2
 Next: 3
 ......

4.3timer

创建一个 Observable, 它在一个给定的延迟后发射一个特殊的值

timer 操作符创建一个在给定的时间段之后返回一个特殊值的 Observable

timer 返回一个 Observable,它在延迟一段给定的时间后发射一个简单的数字 0。 timer 操作符默认在 computation 调度器上执行。

Observable.timer(2, TimeUnit.SECONDS)
        .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                // 2秒后打印
                Log.d(TAG, "Next: " + aLong);
            }
        });

// 执行结果
 Next: 0

5、range()

同时发送一定范围的事件序列

Observable.range(2, 5)
          .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
              System.out.println(integer);
            }
          });

输出

2
3
4
5
6

参考

1、RxJava(三):创建操作符
2、https://juejin.cn/post/6844903617124630535#heading-2

以上是关于Android :RxJava学习笔记之创建操作符的主要内容,如果未能解决你的问题,请参考以下文章

Android :RxJava学习笔记之过滤操作符

Android :RxJava学习笔记之条件/布尔操作符

Android :RxJava学习笔记之转换操作符

Android :RxJava学习笔记之Single

Android :RxJava学习笔记之 错误处理

Android :RxJava学习笔记之Subject