本文为博主原创文章,转载请注明出处

前言

本文总结项目中常用的 Rxjava2 操作符。

CV大神

使用RxJava2原因

  • ★★★★★ 封装了线程切换,不用自己封装线程池、Handler了
  • ★★★★☆ 链式调用,一气呵成

单值发射

Single:大多数场景都是单值发射,所以使用 Single 即可覆盖大部分场景。

Case1: 在非UI线程执行且不关注结果

  • fromCallable
Single.fromCallable(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {Logger.d(TAG, "test: fromCallable() invoked on %s", Thread.currentThread().getName());return generateRandom();}}).subscribeOn(Schedulers.io()).subscribe();

从名字 Callable 就能看出,这是个回调函数,在 io 线程运行

  • defer
        Single.defer(new Callable<SingleSource<Integer>>() {@Overridepublic SingleSource<Integer> call() throws Exception {Logger.d(TAG, "test: defer() invoked on %s", Thread.currentThread().getName());return Single.just(generateRandom());}}).subscribeOn(Schedulers.io()).subscribe();

注意,不能直接使用 Single.just(generateRandom()).subscribeOn(Schedulers.io()).subscribe(),这么写将直接在当前线程调用 generateRandom() ,无法实现在 io 线程执行的效果。

Case2: 在非UI线程执行并关注结果

需要关注结果的场景,建议都订阅 Consumer<Throwable>,因为 RxJava 内部捕获了 Exception,导致外部无感知

        Single.fromCallable(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return generateRandom();}}).subscribeOn(Schedulers.io()).subscribe(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) throws Exception {Logger.d(TAG, "test: accept(Integer integer) invoked on %s", Thread.currentThread().getName());}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Logger.d(TAG, "test: accept(Throwable throwable) invoked on %s", Thread.currentThread().getName());}});

Case3: 在非UI线程执行但在UI线程关注结果

        Single.fromCallable(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return generateRandom();}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) throws Exception {Logger.d(TAG, "test: accept(Integer integer) invoked on %s", Thread.currentThread().getName());}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Logger.d(TAG, "test: accept(Integer integer) invoked on %s", Thread.currentThread().getName());}});

Case4: 变换返回值

        Single.fromCallable(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return generateRandom();}}).map(new Function<Integer, String>() {@Overridepublic String apply(Integer integer) throws Exception {return String.valueOf(integer + "_mapped");}}).subscribe(new Consumer<String>() {@Overridepublic void accept(String s) throws Exception {Logger.d(TAG, "test: " + s);}});

Case5: 按顺序做某事且下一件事依赖上一件事的结果[常用于网络请求接口依赖时]

        Single.defer(new Callable<SingleSource<String>>() {@Overridepublic SingleSource<String> call() throws Exception {return getUserId();}}).flatMap(new Function<String, SingleSource<UserInfo>>() {@Overridepublic SingleSource<UserInfo> apply(String userId) throws Exception {return getUserInfo(userId);}}).subscribeOn(Schedulers.io()).subscribe(new Consumer<UserInfo>() {@Overridepublic void accept(UserInfo userInfo) throws Exception {Logger.d(TAG, "test: get userInfo success: " + userInfo);}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Logger.e(TAG, "test: get userInfo error.", throwable);}});

Case6: 并发读取不同数据源,转换成同类型后,合并

        Single<IBook> novel = Single.fromCallable(new Callable<Novel>() {@Overridepublic Novel call() throws Exception {return getNovel();}}).map(new Function<Novel, IBook>() {@Overridepublic IBook apply(Novel novel) throws Exception {return new NovelAdapter(novel);}}).subscribeOn(Schedulers.io());Single<IBook> rxJava2Tutorial = Single.fromCallable(new Callable<RxJava2Tutorial>() {@Overridepublic RxJava2Tutorial call() throws Exception {return getRxJava2Tutorial();}}).map(new Function<RxJava2Tutorial, IBook>() {@Overridepublic IBook apply(RxJava2Tutorial rxJava2Tutorial) throws Exception {return new RxJava2TutorialAdapter(rxJava2Tutorial);}}).subscribeOn(Schedulers.io());Single.zip(novel, rxJava2Tutorial, new BiFunction<IBook, IBook, List<IBook>>() {@Overridepublic List<IBook> apply(IBook iBook, IBook iBook2) throws Exception {List<IBook> books = new ArrayList<>(2);books.add(iBook);books.add(iBook2);return books;}}).subscribe(new Consumer<List<IBook>>() {@Overridepublic void accept(List<IBook> iBooks) throws Exception {Logger.d(TAG, "test: books are " + iBooks);}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Logger.d(TAG, "test: get books error.", throwable);}});

多值发射

Observable:使用场景较少,比如搜索功能需要不断发射搜索关键字。

Case1: 搜索频率限制

        Observable.create(new ObservableOnSubscribe<String>() {@Overridepublic void subscribe(final ObservableEmitter<String> emitter) throws Exception {mEditText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {if (!emitter.isDisposed()) {emitter.onNext(s.toString().trim());}}});}}).debounce(200, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {@Overridepublic void accept(String keyword) throws Exception {mTextView.setText(search(keyword));}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Logger.e(TAG, "test: emitter keyword error.", throwable);}});

背压

Flowable:使用场景最少,目前仅发射下载进度时可以用上。

Demo 地址

Click Here

总结

陈康肃公善射,当世无双 ,公亦以此自矜。尝射于家圃,有卖油翁释担而立,睨之久而不去。见其发矢十中八九,但微颔之。
康肃问曰:”汝亦知射乎?吾射不亦精乎?”翁曰:”无他, 但手熟尔。”康肃忿然曰:”尔安敢轻吾射!”翁曰:”以我酌油知之。”乃取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿。因曰:”我亦无他,惟手熟尔。”康肃笑而遣之。

RxJava2操作符总结相关推荐

  1. TouTiao开源项目 分析笔记10 实现通用普通文章片段页面

    1.RxJava的Observable数据操作符总结 1.1.Map操作符 Map操作符对原始Observable发射的没一项数据应用一个你选择的函数, 然后返回一个发射这些结果的Observable ...

  2. Retrofit2 的简单使用

    友情链接Rx: Rxjava2操作符(一) Rxjava2操作符(二) Rxjava2操作符(三) Retrofit2介绍 demo地址:github 1. 简介 Retrofit 是一个用于 And ...

  3. 快速从入门到精通,建议细读

    前言 我们程序员之所以担心35岁被裁员,是因为自己的经验和实力能力不符合,国内IT现状,大多数程序员都在外包公司工作,框架老化,代码就是为了完成任务而写,刚定好需求你做一半产品突然让你改需求--一切的 ...

  4. RxJava 2.x 优秀学习资源

    说明:本文主要是记录Rxjava 2.x 网上优秀博客 链接,便于学习所用. Rxjava2.x GitHub链接 https://github.com/ReactiveX/RxJava RxAndr ...

  5. Android开发 - 收藏集

    Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity的显示之ViewRootImpl初探 Activity的显示之Window和View ...

  6. Android 知识梳理目录 - 好吧,这是一个很“干,android物联网开发从入门到实战

    3.1 Retrofit 知识梳理 Retrofit 知识梳理(1) - 流程分析 Retrofit 知识梳理(2) - Retrofit 动态代理内部实现 3.2 OkHttp 知识梳理 OkHtt ...

  7. Android 知识梳理目录 - 好吧,这是一个很“干,安卓系列学习进阶视频

    ============== 2.1 Activity 知识梳理 Activity 知识梳理(1) - Activity 生命周期 Activity 知识梳理(2) - Activity 栈 Acti ...

  8. 一线互联网移动架构师360°全方面性能调优,年薪超过80万!

    Android全局异常处理 在做android项目开发时,大家都知道如果程序出错了,会弹出来一个强制退出的弹出框,这个本身没什么问题,但是这个UI实在是太丑了,别说用户接受不了,就连我们自己本身可能都 ...

  9. RxJava2 转换操作符之FlatMap()方法

    前言: 本篇基于Map操作符,阅读该篇请确保,你已经了解过它:RxJava2 转换操作符之Map()方法.一如既往,干大事的人都是直接先上图,再解释的.(建议用PC端阅读,图片可以放大.排版,也有利于 ...

  10. Rxjava2原理流程+操作符+线程切换 浅析~

    0.前言 没拜读过强大的代码就建议去稍微看一下rxjava2的原理,并不难懂.写的非常的好,也能领略到大佬写的代码有多么的强.里面的设计模式真的牛逼 1.Rxjava2 Rxjava2用于我们来做响应 ...

最新文章

  1. IDEA中 30 秒生成 Spring Cloud Alibaba 工程
  2. 【深度学习】深入浅出 CRF-RNN Layer(The End-to-end)
  3. very_confusing
  4. Fire!——两个BFS
  5. python的优点有哪些-python的优点和缺点是什么?
  6. kickstart技术安装操作系统
  7. ElasticSearch之elasticsearch-users用法及修改集群密码
  8. Aras Innovator PLM二次开发
  9. ST、SC、FC、LC光纤接头区别?
  10. 第四章 SQL语法分类
  11. iOS 苹果官方Demo
  12. PS更改图片的背景颜色
  13. 养老保险怎么缴最划算?应该少交还是多交?
  14. 计算机一级考试ps知识点,计算机一级考试PS备考训练题及答案
  15. uniapp:在HBuilderX里使用夜神模拟器
  16. Linux 磁盘分区挂载
  17. java毕业设计苹果酒店住房管理源码+lw文档+mybatis+系统+mysql数据库+调试
  18. HDU1435 Stable Match 【稳定婚姻问题】
  19. 【沃顿商学院学习笔记】商业基础——Operation Management:02运营管理活动中的详细流程分析
  20. pyqt5如何循环遍历控件名_PyQt5 控件学习(一个一个学习之QObject对象)

热门文章

  1. GNSS常识--Multi-GNSS信号 频率与波长统计以及在rtklib中的频率索引
  2. pytorch分类和回归:阿里天池宠物年龄预测
  3. 智能家居-耗电情况总览
  4. MySQL基本语句(一)查询语句
  5. 【水文学法总结】河道内生态流量计算方法(含MATLAB实现代码)
  6. 盛世昊通:造车新势力产销增长,汽车行业更上一层楼
  7. 《一步一脚印 90后程序员》12
  8. cisco网络学习随笔----绝对"绝版"
  9. 杭州电子科技大学计算机组成原理期末试卷,杭州电子科技大学计算机组成原理期末样卷(B)...
  10. python:基于flask有道智云API在线翻译网页