Rxjava

1.创建符

1.1 Observable

创建函数用于创建一个Observable对象,它们都是Observable的静态方法,通过Observable.创建

1.create

	Observable.create(emitter -> {
             emitter.onNext(1);
             emitter.onNext(2);
             emitter.onComplete();
         }
    );

2.from

	Observable.fromArray(1, 2, 3);
    Observable.fromArray(new int[]{1,2,3});
    Observable.fromArray(new ArrayList());
    
	Observable.fromIterable(new HashSet<>());

	Observable.fromCallable(new Callable<String>() {
         @Override
         public String call() throws Exception {
             return getString();					//通过某个函数获取要发送的值
         }
    });
    
	Observable.fromFuture(Future<? extends T> future);

4.defer
直到有观察者订阅时,才动态创建被观察者对象

	Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
         @Override
         public ObservableSource<? extends Integer> call() throws Exception {
              return Observable.just(i);
         }
    });
    
	Observable.defer(()->Observable.just(i));			

5.timer
延迟指定时间后,发送一个Long类型的数值0

	Observable.timer(10, TimeUnit.SECONDS);

6.interval
每个一段时间发送一个从0递增的Long型整数,0,1,2,3…

	//每隔10s发送一个整数,初始延迟为10s
	Observable.interval(10, TimeUnit.SECONDS)
	//每隔10s发送一个整数,初始延迟为5s
	Observable.interval(5, 10, TimeUnit.SECONDS)

7.range

	Observable.range(10, 5)			//发送10,11,12,13,14共5个整数

8.amb
接收多个数据源,但只会发射最先试图发射的数据源,其他的都会被过滤掉,例如:

	//在这个例子中,观察者只会观察到1,2,3
	Observable.ambArray(Observable.just(1, 2, 3), Observable.just(4, 5, 6), Observable.just(7, 8, 9))
	//在这个例子中,观察者只会观察到4, 5, 6
	Observable.ambArray(Observable.just(1, 2, 3).delay(1, TimeUnit.SECONDS), Observable.just(4, 5, 6))
1.2 发射单个数据

Observable可以同来发射一连串的事件,而SingleCompletableMaybe用来创建只能发射一个数据或事件的被观察者
它们的创建方法和Observable非常相似,都是调用自身的静态方法,这里主要记录三者的区别:

首先观察者可能会观察到这样一些事件:

onSuccess(Object o) 			//观察者通过这个回调接收一个数据,在Observable类的观察者类中这个方法叫做onNext
onComplete() 					//用来观察事件完成发射的事件,没有参数所以并不能传递数据
onError(Throwable e)			//用来观察事件

Single类只能发射单个数据,或者单个错误,不能发射完成事件

public interface SingleObserver<T>{
	onSubscribe(Disposable d);
	onSuccess(T t);
	onError(Throwable e);
}

Completable类能发射单个完成事件,或单个错误,不能发射数据

public interface CompletableObserver<T>{
	onSubscribe(Disposable d);
	onComplete();
	onError(Throwable e);
}

Maybe类能发射单个数据,或者单个错误,或单个完成事件

public interface MaybeObserver<T>{
	onSubscribe(Disposable d);
	onSuccess(T t);
	onComplete();
	onError(Throwable e);
}

需要注意的是,这些类只能发射一个事件,以Maybe为例,它不能发射一个数据和一个完成事件,只能发射一个数据或一个完成事件,例如:

	Maybe.create(emitter -> {
         emitter.onComplete();
         emitter.onSuccess("s");
         emitter.onError(new NullPointerException());
   })

上面的的例子中,观察者只会观察到完成事件,数据会被忽略,错误事件也无法被观察者接住,导致程序崩溃,发射的东西必须是三选一;Single和Completable也是同理。

1.3 Flowable背压:

背压是指数上游据源发送数据速率过快,而下游观察者处理数据过慢,导致数据积压在缓存中,最终导致内存溢出
Rxjava提供了新的数据发射器Flowable和新的观察者Subscriber解决背压问题

	Flowable.create(emitter -> emitter.onNext(0), BackpressureStrategy.ERROR)	//1.create方法中多了背压策略
	          .subscribe(new Subscriber<Object>() {
                     @Override
                     public void onSubscribe(Subscription s){	//2.onSubscribe参数变成了Subscription
                         s.request(3);							//3.设置下游只接收3条消息,多余的还是会存在缓存
                    	 s.request(4)							//如果调用两次request,下游将会接收3+4=7条消息
                     }
                     @Override
                     public void onNext(Object o) {
                     
                     }
                     @Override
                     public void onError(Throwable t) {

                     }

                     @Override
                     public void onComplete() {

                     }
            }

背压策略:

public enum BackpressureStrategy {
    MISSING,			//相当于没有指定背压策略
    ERROR,				//Flowable缓存池(大小128)溢出会抛出一个MissingBackpressureException
    BUFFER,				//缓存无穷大
    DROP,				//如果Flowable缓存池满了,会丢掉数据源新发送的消息
    LATEST
}

数据上游获取消息缓存数量:
FlowableEmitter相比ObservableEmitter多了requested这个方法:

public interface FlowableEmitter<T> extends Emitter<T> {
    void setDisposable(Disposable s);
    void setCancellable(Cancellable c);
    long requested();
    boolean isCancelled();
    FlowableEmitter<T> serialize();
}

Flowable发送数据并是直接发送给下游,而是发送给缓存,缓存再把数据转发给下游
requested方法可以获取缓存池还能放几条消息,当request方法返回0时,说明缓存池已经满了,上游应当暂停发射消息;

通过Flowable得到一个背压的解决方案:

    Flowable.create(emitter -> {
                while (true) {
                    if (emitter.requested() == 0) continue;		//缓存装满,暂停发送数据
                    emitter.onNext(0);
                }
            }
            , BackpressureStrategy.MISSING)
            .subscribeOn(Schedulers.newThread())
            .observeOn(Schedulers.newThread())
            .subscribe(new Subscriber<Integer>() {
            
                    Subscription subscription;

                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(1);
                        subscription = s;
                   }

                   @Override
                   public void onNext(Integer n) {
                        handle(n);								//模拟一个耗时操作
                        subscription.request(1);				//处理完消息再允许缓存释放一个消息
                   }

                   @Override
                   public void onError(Throwable t) {

                   }

                   @Override
                   public void onComplete() {

                   }
             }
       );
1.4 Subject:

2.操作符

操作符都是Observable的非静态方法,在创建Observable对象之后对它进行一些变换操作

2.1 过滤操作符:

防抖
可以通过防抖避免频繁触发某事件,如果在试图发射事件之后的n秒后没有再次发射事件,那么这个事件才会通过debounce过滤,真正发射出来,例如:

	Observable.create(emitter -> {
                emitter.onNext(0);			//t = 0
                Thread.sleep(1000);
                emitter.onNext(1);			//t = 1000时,距离上一个时间触发只有1000ms,所以0不会被观察到
                							//t = 3000时,距离上一个时间触发达到2000ms,所以1会被观察到
   }).debounce(2, TimeUnit.SECONDS)

所以debounce是自带延时的,如果防抖时间为n秒,那么观察者看到事件的时刻总是比实际发射时刻晚n秒

其他

	//take和skip,是相反的操作符
	Observable.just(1, 2, 3, 4, 5).take(3)									//订阅者只能接收到1,2,3
	take(n, TimeUnit.SECONDS)												//订阅者只能接收到前n秒发送的消息

	Observable.just(1, 2, 3, 4, 5).takeLast(3)								//订阅者只能接收到3,4,5
	takeLast(n, TimeUnit.SECONDS)											//订阅者只能接收到最后n秒发送的消息
	
	Observable.just(1,2,3,4,3,4,5).distinct()					//1,2,3,4,5
	Observable.just(1,3,3,4,3,4,5).distinctUntilChanged()		//1,3,4,3,4,5
	
	Observable.just(1,2,"3").ofType(Integer.class)				//过滤出某种类型的数据
	Observable.just(1, 2, 3).filter(i -> i > 2)					//自定义过滤条件
条件操作符:

通过条件操作符可以使得不符合条件的数据源产生错误
1.single
single保证了数据源只能发送一个数据,它的参数指定了没有数据发送时的默认发送值

	Observable.just(1).single(1)				//发射1
	Observable.just(12).single(1)				//报错
	Observable.empty().single(2)				//发射2

2.all
判断是否每个数据都满足某个条件,通过all的多个数据会被转化为一个boolean值

	Observable.just(1, 2, 3).all(i -> i < 4)	//发射true
	Observable.just(1, 2, 3).all(i -> i < 3)	//发射false

3.contain
判断是否每个数据都满足某个条件,通过all的多个数据会被转化为一个boolean值

	Observable.just(1, 2, 3).contains(3)		//发射true
变换操作符:

1.map,flatMap
以下两种写法是相同的效果,flatMap完全可以实现map的所有功能

	Observable.just(123).map(n->2*n)
	Observable.just(123).flatMap(n->Observable.just(2*n))

flatMap接收一个Function做为参数,它的作用就是把T类型的参数变成R类型的参数:

public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper)

public interface Function<T, R> {
    R apply(@NonNull T t) throws Exception;
}

可以看到flatMap使用被发射的数据重新创建了一个数据源,一个数据源又可以包含多个数据,可以使用flatMap方便地完成一对多的映射

2.flatMap和concatMap的区别:
经过flatMap变换后的数据不一定保持原来的顺序,而concatMap变换后数据一定会保持原始顺序,例如:

	//如果事件2的发射遇到一些延时,观察者接收到的消息顺序就会变成1,3,2
	Observable.just(1,2,3).flatMap(n->Observable.just(n)).subscribe()		
	//不论发生什么,观察者一定会按1,2,3的顺序接收到数据	
	Observable.just(1,2,3).concatMap(n->Observable.just(n)).subscribe()			

3.cast
作用是把数据源的每一个数据都做类型强制转换,例如:

	Observable.just(1,2,3).case(String.class)

4.concatWith和mergeWith
把两个事件序列合并成一个事件序列,区别只是在于数据合并后是否按合并前的顺序被观察者接收到

 	Observable.just(1,2,3)
 		.delay(1, TimeUnit.SECONDS)
 		.concatWith(Observable.just(4,5,6))			//发射1,2,3,4,5,6
 		
	Observable.just(1,2,3)
		.delay(1, TimeUnit.SECONDS)
		.mergeWith(Observable.just(4,5,6))			//发射4,5,6,1,2,3

5.zipWith
把两个事件序列压缩为一个,参数是另外一个事件源,和一个用来说明压缩规则的函数

   Observable.just(1, 2, 3, 4).zipWith(Observable.just(4, 5, 6), (a, b) -> a + b);	//发射5,7,9

6.reduce
把一个事件序列通过某种算法压缩成Maybe类型发送给观察者

	Observable.just(1, 2, 3, 4).reduce((a, b) -> a + b)			//发射10(1+2+3+4=10)

7.compose
compose操作符的作用是为了避免链式调用时出现过多的模板代码,例如:

	repository.login()
		.subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())

如果不想在每个网络请求下面写同样的代码,可以使用compose将这些代码封装起来,就会好看很多
compose方法的参数是一个Transformer对象,首先定义一个方法返回Transformer对象,Transformer定义如下:

public interface ObservableTransformer<Upstream, Downstream> {
    ObservableSource<Downstream> apply(@Observable<Upstream> upstream);
}

可以看到它的唯一方法apply是将一个Observable变换成另一个Observable;
首先写一个返回类型为Transformer的方法,这个Transformer中封装线程切换的操作符:

	 <T> ObservableTransformer<T, T> applySchedulers() {
        return observable -> observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

然后就可以使用compose操作符:

	repository.login().compose(applySchedulers())
2.5 其他操作符:

retry和repeat
数据源发射error时会触发retry,发射complete时会触发repeat;
retry(n)在数据源发射error后使数据再重发至多n次,repeat(n)在数据源发射complete后再使数据重发至多n次;
retry()会一直重试直到没有error发射,repeat()会一直重复直到有error发射
retry(Predicate)可以自定义某些error不触发重试

retryWhen
retryWhen接收一个Function作为参数:

public final Observable<T> retryWhen(Function<Observable<Throwable>, ObservableSource<?>> handler) 

public interface Function<T, R> {
    R apply(T t) throws Exception;
}

Function的作用是将Observable<Throwable>转化为另一个Observable,这个Observable的类型决定了是否会重新触发事件源发射事件,例如:

      Observable.create(emitter -> {
          emitter.onNext(1);
          emitter.onError(new NullPointerException());
      }).retryWhen(throwableObservable -> {
      		//这里要用flatMap把Observable<throwable>转换为其他消息
         	throwableObservable.flatMap(throwable ->
         		//返回Error事件后,观察者会接收到这个错误
                Observable.error(new RuntimeException()))	
                // 返回next事件后,观察者会收到无穷多的1,这里onNext的参数是什么都无所谓,重要的是触发onNext
                // Observable.just(0))		
      }).subscribe(data -> {
          print(data);
      }, throwable -> {
          print(throwable.toString());
      });
03-21
### 关于 RxJava 的使用指南和教程 #### 什么是 RxJavaRxJava 是一种基于响应式编程(Reactive Programming)的库,用于处理异步数据流。它通过观察者模式简化了复杂的异步操作,并提供了丰富的操作符来组合、转换和过滤数据流。 --- #### RxJava 的基本概念 RxJava 的核心组件包括以下几个部分: - **Observable/Flowable**: 数据源,表示可被订阅的数据流。 - **Observer/Subscriber**: 订阅者,接收来自 Observable 或 Flowable 的通知。 - **onNext()**: 接收正常的数据项。 - **onError()**: 处理错误情况。 - **onComplete()**: 表示数据流结束[^2]。 --- #### 如何开始使用 RxJava? ##### 添加依赖 要使用 RxJava,在项目的 `build.gradle` 文件中添加以下依赖: ```gradle implementation 'io.reactivex.rxjava3:rxjava:3.1.5' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' ``` 注意:上述版本号可能随时间更新,请查阅官方文档获取最新版本[^4]。 --- #### 基本使用方式 ###### 方法一:分步骤实现 这是为了深入了解 RxJava 的工作原理。以下是具体的步骤: 1. 创建一个 Observable 对象。 2. 定义 Observer 来监听事件。 3. 调用 subscribe() 方法将两者连接起来。 代码示例: ```java // 步骤1:创建Observable对象 Observable<String> observable = Observable.just("Hello", "World"); // 步骤2:定义Observer Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String value) { System.out.println(value); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onComplete() { System.out.println("Completed"); } }; // 步骤3:建立订阅关系 observable.subscribe(observer); ``` ###### 方法二:链式调用 这种方式更适合实际项目中的简洁性和高效性。可以通过链式调用来完成复杂的操作: 代码示例: ```java Observable.just("Hello", "World") .map(s -> s.toUpperCase()) // 将字符串转为大写 .subscribe(System.out::println); // 输出结果 ``` --- #### 组合与合并操作符详解 RxJava 提供了许多强大的操作符来帮助开发者灵活地处理数据流。常见的组合与合并操作符如下: 1. **merge():** 合并多个 Observables 并保持顺序不固定[^1]。 ```java Observable.merge(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 2. **concat():** 类似 merge,但会按顺序依次发射数据。 ```java Observable.concat(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 3. **zip():** 将多个 Observables 发射的数据按照指定的方式组合在一起。 ```java Observable.zip( Observable.just("A", "B"), Observable.just("C", "D"), (s1, s2) -> s1 + "-" + s2) .subscribe(System.out::println); ``` --- #### Retrofit 结合 RxJava 使用 Retrofit 和 RxJava 可以很好地配合使用,从而简化网络请求流程。首先需要配置 Retrofit 支持 RxJava: 代码示例: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); // 定义接口 interface ApiService { @GET("/data") Observable<List<Data>> getData(); } ApiService apiService = retrofit.create(ApiService.class); // 执行请求 apiService.getData().subscribe(dataList -> { dataList.forEach(item -> System.out.println(item)); }, throwable -> { throwable.printStackTrace(); }); ``` --- #### 更多资源推荐 如果想进一步学习 RxJava,可以参考以下资料: - Carson_Ho 的《Android RxJava 实际应用教学》[^3]。 - 一份详细的 RxJava 学习指南[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值