rxjava要点简介

xiaoxiao2022-07-06  6


某平台价值19860元的编程课程资料免费领取【点我领取】


rxjava用来干什么

举例子吧。

某个地方不定期地发放个人娱乐用品,小张喜欢这些用品,希望每次都能被通知过来领取享受一把。

rxjava就是能让小张实现愿望的一个社团机构。

在以上的例子中,rxjava负责以下工作:

1.主动发起发放娱乐用品活动,每次都由rxjava主办;

2.每次搞活动时候,rxjava都派人通知小张过来领取当场享受;

所以,切回程序框架的角度,

rxjava可以用来实现这种需求场景:针对连续多次发生的事情或者多个数据进行分发给参与者处理。

例如100个图片文件的读取,每读取完一个文件后就调用参与者处理函数进行处理,参与者可能会拿着图片文件进行显示,也可能拿着文件保存到别的地方。

rxjava的特点

前面说的,仅仅是rxjava的功能,rxjava的优点肯定不仅仅是表面功能那么简单。

如果仅仅是对于多次发生的事情分发给参与者处理,那简单地用循环调用参与者的处理函数就ok了,何必用rxjava? 

在此,特介绍一下rxjava的特点:

1.异步的便捷实现;

例如很简单就能实现数据读取过程在某个线程,而参与者处理数据又在另外的线程,或者在ui线程。

2.代码编写易读性;

使用起来的接口调用过程容易阅读和理解,方便后期维护。

3.数据源变换方便;

例如数据源是整数,但是订阅者需要处理的是字符串,通过rxjava可以便捷地做变换。

rxjava要点记录

创建事件源的不同方法

直接提供实现函数

参考下面例子,直接提供一个OnSubscribe回调实现:

Observable observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("1"); subscriber.onNext("2"); subscriber.onNext("3"); subscriber.onCompleted(); } }); just

直接通过参数提供数据源来发生事件(每项数据一次事件)。

看例子:

Observable observable = Observable.just("1", "2", "3"); from

从数组或者序列中提供数据源来发生事件(每项数据一次事件)。

abservable.subscribe的理解

注:函数名修改为“abservable.subscribedBy()”可能更好理解。

使用时候这么写:

Observable.from(names).subscribe(subscriber);

意思是:subscriber向abservable进行subscribe,而不是abservable向subscriber进行subscribe。

也就是订阅者向提供方进行订阅动作,此时提供方会内部遍历事件/数据,依次提供给订阅者参与处理。

异步线程处理

rx提供的线程:

Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。Schedulers.trampoline:在当前线程运行,不过不是立即运行,而是丢到队列中后面再运行。Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。Schedulers.io(): I/O 操作线程。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。Schedulers.computation(): 计算线程。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。AndroidSchedulers.mainThread(),操作在 Android 主线程运行。

例子:

Observable.just(1, 2, 3, 4) .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程 .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程 .subscribe(subscriber);

map

用map的原因:

数据源类型和订阅者处理数据类型如果一致,这样就行:

Observable.just(1, 2, 3, 4) .subscribe(new Action1<Integer>() { public void call(Integer number) { log("number:" + number); } });

但是,如果遇到数据源类型和订阅者期望处理的类型不一样,就需要一个转换。

map就是为了帮忙转换而被设计出来,map在此的意思是,把数据源类型映射转换为新类型。

例如上面的例子中订阅者希望处理的是字符串,用map转换一下:

Observable.just(1, 2, 3, 4) .map(new Func1<Integer,String>(){ public String call(Integer value){return Integer.toString(value);} }) .subscribe(new Action1<String>() { public void call(String number) { log("number:" + number); } });

flatMap和map差异

map针对的是:一一对应地把数据源每一项数据转换为指定的类型,然后给订阅者享用。

如果,订阅者比较懒,希望处理的是每项数据里面的N项子数据,那怎么办? 

例如,某个情景下订阅者处理的是每个人员姓名,那么只需用map(人员,姓名)这种方式,

某天,订阅者突然改变注意,希望处理每位人员的借阅的每一本书,这时候map就搞不定了,因为map只能一一对应地转换,没法一换多。

这时候flatMap就可以帮忙解决这个问题了。

看代码:

TPerson[] personlist = {... 演示忽略...}; Subscriber<Book> subscriber = new Subscriber<Book>() { public void onNext(Book book) { // do sth... } }; Observable.from(personlist) .flatMap(new Func1<TPerson, Observable<Book>>() { public Observable<Course> call(TPerson person) { return Observable.from(person.getBooks()); } }) .subscribe(subscriber);

从代码中可以看出,faltMap的原理,其实是把数据源的每一项展开为一个子数据源,然后再给订阅者享用。

“把数据源的每一项展开为一个子数据源”这个过程,rxjava作者认为是一个“flat”的过程,所以叫flatMap。

 

 

 

 

 

本文结束。

转载请注明原文地址: https://www.6miu.com/read-4968551.html

最新回复(0)