RxJava2 基础使用

匿名 (未验证) 提交于 2019-12-02 21:53:52

RxJava

summary

  1. 介绍订阅模式/基本语法
  2. 介绍线程切换的订阅
  3. 介绍变化操作符
  4. 背压解决方法和操作符
  5. 介绍和retrofit使用
  6. Lambda表达式
  Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {             @Override             public void subscribe(ObservableEmitter<Integer> e) throws Exception {                 e.onNext(1);                 e.onNext(2);                 e.onNext(3);             }         });          Observer observer = new Observer() {             @Override             public void onSubscribe(Disposable d) {             }              @Override             public void onNext(Object value) {                 Log.d(":", value.toString());             }             @Override             public void onError(Throwable e) {             }             @Override             public void onComplete() {             }         };         //         Consumer consumer = new Consumer() {             @Override             public void accept(Object o) throws Exception {              }         };         observable.subscribe(consumer);          observable.subscribe(observer);
private void threadRxjava2() {         Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {             @Override             public void subscribe(ObservableEmitter<Integer> e) throws Exception {                 e.onNext(1);             }         });         Consumer consumer = new Consumer() {             @Override             public void accept(Object o) throws Exception {                 Log.d("处理事件", "");             }         };         /**          * Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作          Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作          Schedulers.newThread() 代表一个常规的新线程          AndroidSchedulers.mainThread() 代表Android的主线程          */         //只有初次指定有效其余无效         //订阅事件执行在新线程         observable.subscribeOn(Schedulers.newThread())                 //每执行一次切换下游线程,都会产生效果                 //观察事件执行在主线程                 .observeOn(AndroidSchedulers.mainThread())                 .subscribe(consumer);      }

singleobserver/completableobserver

如果你使用一个单一连续事件流,即只有一个onNext事件,接着就触发onComplete或者onError,这样你可以使用Single。

如果你的观察者连onNext事件都不关心,你可以使用Completable,他只有onComplete和onError两个事件

Disposable

用于解除订阅
创建一个可被 CompositeDisposable 管理的 observer
生命周期可控制订阅和解除订阅
避免发生内存泄漏

 private static final String TAG = DisposableExampleActivity.class.getSimpleName();     Button btn;     TextView textView;     private final CompositeDisposable disposables = new CompositeDisposable();      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_example);         btn = (Button) findViewById(R.id.btn);         textView = (TextView) findViewById(R.id.textView);         btn.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 doSomeWork();             }         });     }      @Override     protected void onDestroy() {         super.onDestroy();         disposables.clear(); // do not send event after activity has been destroyed     }      /*      * Example to understand how to use disposables.      * disposables is cleared in onDestroy of this activity.      */     void doSomeWork() {         disposables.add(sampleObservable()                 // Run on a background thread                 .subscribeOn(Schedulers.io())                 // Be notified on the main thread                 .observeOn(AndroidSchedulers.mainThread())                 .subscribeWith(new DisposableObserver<String>() {                     @Override                     public void onComplete() {                         textView.append(" onComplete");                         textView.append(AppConstant.LINE_SEPARATOR);                         Log.d(TAG, " onComplete");                     }                      @Override                     public void onError(Throwable e) {                         textView.append(" onError : " + e.getMessage());                         textView.append(AppConstant.LINE_SEPARATOR);                         Log.d(TAG, " onError : " + e.getMessage());                     }                      @Override                     public void onNext(String value) {                         textView.append(" onNext : value : " + value);                         textView.append(AppConstant.LINE_SEPARATOR);                         Log.d(TAG, " onNext value : " + value);                     }                 }));     }      static Observable<String> sampleObservable() {         return Observable.defer(new Callable<ObservableSource<? extends String>>() {             @Override             public ObservableSource<? extends String> call() throws Exception {                 // Do some long running operation                 SystemClock.sleep(2000);                 return Observable.just("one", "two", "three", "four", "five");             }         });     } 

实现定时调度任务的操作符:

  • timer:创建型操作符,用于延时执行任务。

    Observable.timer(2, TimeUnit.SECONDS);
  • interval:创建型操作符,用于周期执行任务。 间隔几秒后执行

    //默认第一次个任务需要延时和指定间隔相同的时间。 Observable.interval(0, 2, TimeUnit.SECONDS);
  • delay:辅助型操作,用于延时传递数据。

    Observable.delay(2, TimeUnit.SECONDS)
  • filter

    Observable.just(1, 2, 3, 4, 5, 6)             .filter(new Predicate<Integer>() {                 @Override                 public boolean test(Integer integer) throws Exception {                     return integer % 2 == 0;                 }             })             .subscribe(getObserver());
  • take 前的事件

  • skip跳过前几个事件
  • last 发射默认最后一个,如果没有则发射设置的默认值

buffer

将要发射的数据封装成多个缓冲区,每次发射一个缓冲区

        Observable<List<String>> buffered = getObservable().buffer(3, 1);          // 3 means,  it takes max of three from its start index and create list         // 1 means, it jumps one step every time         // so the it gives the following list         // 1 - one, two, three         // 2 - two, three, four         // 3 - three, four, five         // 4 - four, five         // 5 - five

map

ObservableEmitter发射器,发射规定参数范型的事件给下游

发射 变换 处理:

public class MapExampleActivity extends AppCompatActivity {      private static final String TAG = MapExampleActivity.class.getSimpleName();     Button btn;     TextView textView;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_example);         btn = (Button) findViewById(R.id.btn);         textView = (TextView) findViewById(R.id.textView);          btn.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 doSomeWork();             }         });     }      /*     * Here we are getting ApiUser Object from api server     * then we are converting it into User Object because     * may be our database support User Not ApiUser Object     * Here we are using Map Operator to do that     */     private void doSomeWork() {         getObservable()                 // Run on a background thread                 .subscribeOn(Schedulers.io())                 // Be notified on the main thread                 .observeOn(AndroidSchedulers.mainThread())                 .map(new Function<List<ApiUser>, List<User>>() {                      @Override                     public List<User> apply(List<ApiUser> apiUsers) throws Exception {                         return Utils.convertApiUserListToUserList(apiUsers);                     }                 })                 .subscribe(getObserver());     }      private Observable<List<ApiUser>> getObservable() {         return Observable.create(new ObservableOnSubscribe<List<ApiUser>>() {             @Override             public void subscribe(ObservableEmitter<List<ApiUser>> e) throws Exception {                 if (!e.isDisposed()) {                     e.onNext(Utils.getApiUserList());                     e.onComplete();                 }             }         });     }      private Observer<List<User>> getObserver() {         return new Observer<List<User>>() {              @Override             public void onSubscribe(Disposable d) {                 Log.d(TAG, " onSubscribe : " + d.isDisposed());             }              @Override             public void onNext(List<User> userList) {                 textView.append(" onNext");                 textView.append(AppConstant.LINE_SEPARATOR);                 for (User user : userList) {                     textView.append(" firstname : " + user.firstname);                     textView.append(AppConstant.LINE_SEPARATOR);                 }                 Log.d(TAG, " onNext : " + userList.size());             }              @Override             public void onError(Throwable e) {                 textView.append(" onError : " + e.getMessage());                 textView.append(AppConstant.LINE_SEPARATOR);                 Log.d(TAG, " onError : " + e.getMessage());             }              @Override             public void onComplete() {                 textView.append(" onComplete");                 textView.append(AppConstant.LINE_SEPARATOR);                 Log.d(TAG, " onComplete");             }         };     } }

flatmap

将上游事件返回的对象进行变换和拆解,flatmap为按照顺序。

private void flatMapRxJava() {         Observable.create(new ObservableOnSubscribe<Integer>() {             @Override             public void subscribe(ObservableEmitter<Integer> e) throws Exception {                 e.onNext(1);                 e.onNext(2);             }             //flatmap根据上游事件的个数执行相应的次数。 <key,Values>         }).flatMap(new Function<Integer, ObservableSource<String>>() {             @Override             //下面的代码示例展示了 JDK 5.0 中集合框架中的 Map 接口的定义的一部分:             //  public interface Map<K, V> {             //  public void put(K key, V value);             //  public V get(K key);             //  }             //范型函数作用是:必须在定义或实例化 Map 类型的变量时为 K 和 V 提供具体的值             public ObservableSource<String> apply(Integer integer) throws Exception {                 ArrayList list=new ArrayList();                 for (int i = 0; i < 3; i++) {                     list.add("I am value " + integer);                 }                 return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);             }         }).subscribe(new Consumer<String>() {             @Override             public void accept(String s) throws Exception {                 Log.d("accept",":"+s);             }         });     } 

我们可以根据需求,选择相应的简化订阅。只不过传入的对象改为了Consumer。

reduce

要把一个被观察者的所有元素都聚合成单一的元素,可以使用reduce操作符,比如把所有元素都加起来。


getObservable()
.reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer t1, Integer t2) {
return t1 + t2;
}
})
.subscribe(getObserver());

merge

多个观察者合并但乱序

 /*      * Using merge operator to combine Observable : merge does not maintain      * the order of Observable.      * It will emit all the 7 values may not be in order      * Ex - "A1", "B1", "A2", "A3", "A4", "B2", "B3" - may be anything      */     private void doSomeWork() {         final String[] aStrings = {"A1", "A2", "A3", "A4"};         final String[] bStrings = {"B1", "B2", "B3"};          final Observable<String> aObservable = Observable.fromArray(aStrings);         final Observable<String> bObservable = Observable.fromArray(bStrings);          Observable.merge(aObservable, bObservable)                 .subscribe(getObserver());     }

concat

跟Merge操作符很像,但是这个操作符是能保证输出顺序的
here - first “A1”, “A2”, “A3”, “A4” and then “B1”, “B2”, “B3”

zip

比如一个界面需要展示用户的一些信息, 而这些信息分别要从两个服务器接口中获取, 而只有当两个都获取到了之后才能进行展示, 这个时候就可以用Zip了:

  Observable.zip(getCricketFansObservable(), getFootballFansObservable(),                 new BiFunction<List<User>, List<User>, List<User>>() {                     @Override                     public List<User> apply(List<User> cricketFans, List<User> footballFans) throws Exception {                         return Utils.filterUserWhoLovesBoth(cricketFans, footballFans);                     }                 })                 // Run on a background thread                 .subscribeOn(Schedulers.io())                 // Be notified on the main thread                 .observeOn(AndroidSchedulers.mainThread())                 .subscribe(getObserver());

scan

scan操作符将Observable的结果在BiFunction扫描一遍后交给Observer使用,scan最大的功用是在BiFunction里面的apply里面做一次计算,有条件、有筛选的输出最终结果

  Observable.just(1, 2, 3, 4, 5);   getObservable()                     // Run on a background thread                 .subscribeOn(Schedulers.io())                             // Be notified on the main thread                             .observeOn(AndroidSchedulers.mainThread())                             .scan(new BiFunction<Integer, Integer, Integer>() {                         @Override                         public Integer apply(Integer int1, Integer int2) throws Exception {                             return int1 + int2;                         }                 })                 .subscribe(getObserver());           }

最终输出1,3,6,10,15

replay

efer的英文意思就是推迟,在这里是推迟Observable的创建,defer操作符是直到有订阅者订阅时,才通过Observable的工厂方法创建Observable,defer能保证Observable的状态是最新的.


public Observable<String> brandDeferObservable() {
return Observable.defer(new Callable<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> call() throws Exception {
return Observable.just(brand);
}
});
}

throttleFirst

如果你需要在一段时间内只响应第一次的操作,比如说一段时间内连续点击按钮只执行第一次的点击操作,throttleFirst操作符就可以满足这个需求

 private void doSomeWork() {         getObservable()                 .throttleFirst(500, TimeUnit.MILLISECONDS)                 // Run on a background thread                 .subscribeOn(Schedulers.io())                 // Be notified on the main thread                 .observeOn(AndroidSchedulers.mainThread())                 .subscribe(getObserver());     }

throttlelast

同上采集最后一个元素

debounce

当一个事件发送出来之后,在约定时间内没有再次发送这个事件,则发射这个事件,如果再次触发了,则重新计算时间。

应用场景举例
需求:在Edittext上添加监听,当里面输入的内容变化后进行搜索。换句话说就是当用户的输入操作停止几秒钟之后再去搜索。

window

swithchmap

replaysubject

publishubject

behavirsubject

asynsubbject

sample

每隔一段时间取出事件

会丢失部分事件;

背部的压力,就是你走得慢了,后面有人推你。
背压是下游控制上游流速的一种手段

onSubscribe回调的参数不是Disposable而是Subscription,多了行代码

FlowableEmitter

  • BackpressureStrategy.DROP和
  • BackpressureStrategy.LATEST这两种策略.
  • BackpressureStrategy.BUFFER

        Flowable<Integer> observable = Flowable.create(new FlowableOnSubscribe<Integer>() {         @Override         public void subscribe(FlowableEmitter<Integer> flowableEmitter) throws Exception {             flowableEmitter.onNext(1);             flowableEmitter.onComplete();         }     }, BackpressureStrategy.BUFFER); //        ,BackpressureStrategy.LATEST); //        ,BackpressureStrategy.DROP);     //设置背压测策略      observable.observeOn(Schedulers.io())             .subscribeOn(AndroidSchedulers.mainThread())             .subscribe(new Subscriber<Integer>() {                 @Override                 public void onSubscribe(Subscription s) {                     s.request(23);                 }                  ........ } 

数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一条流合并为一条新的流。

文章来源: RxJava2 基础使用
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!