目录

  • 目录
  • 主页
  • 中文资料
  • Rxjava是什么
  • 用途
  • 配置 添加依赖即可
  • 基本概念
    • 1. 被观察者. Observable
    • 2. 观察者. Observer
    • 3. 订阅. Subscribe
    • 4. 事件.
    • 5. Scheduler.
  • - 案例1
  • - 案例2
  • - 案例3

案例下载传送门

主页

  • Rxjava
  • RxAndroid

中文资料

  • 给 Android 开发者的 RxJava 详解
  • RxJava 2.x 教程

Rxjava是什么

首先要了解什么是观察者

Android 开发中一个比较典型的例子是点击监听器 OnClickListener 。对设置 OnClickListener 来说, View 是被观察者, OnClickListener 是观察者,二者通过 setOnClickListener() 方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的 OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。

如图所示,通过 setOnClickListener() 方法,Button 持有 OnClickListener 的引用(这一过程没有在图上画出);当用户点击时,Button 自动调用 OnClickListener 的 onClick() 方法。另外,如果把这张图中的概念抽象出来(Button -> 被观察者、OnClickListener -> 观察者、setOnClickListener() -> 订阅,onClick() -> 事件),就由专用的观察者模式(例如只用于监听控件点击)转变成了通用的观察者模式。如下图:

用途

  • 异步操作
  • 在逻辑复杂的情况下, 仍然可以让代码逻辑保持简洁

配置 添加依赖即可

    在com.android.tools.build:gradle 3.0 以上版本依赖在gradle 中的声明写法implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'implementation 'io.reactivex.rxjava2:rxjava:2.x.y'在com.android.tools.build:gradle 3.0 以下版本依赖在gradle 中的声明写法compile 'io.reactivex.rxjava2:rxandroid:2.0.2'compile  'io.reactivex.rxjava2:rxjava:2.x.y'

基本概念

1. 被观察者. Observable

    - 作用:决定什么时候出发时间以及出发怎样的事件- 创建方法:Observable.just (T t) //参数为单个的Observable.flapMap() //参数为多个的Observable.from (T [] t) //参数为数组Observable.from (Iterable <? extends T>) //参数为Iterable (ArrayList的一种实现)

2. 观察者. Observer

    - 作用:当事件触发的时候将有怎样的行为
    - 实现类:
Observer  \ Subscriber

3. 订阅. Subscribe

    - 作用:使被观察者与观察者建立联系
    -方法:
observable.subscribe(observer);observable.subscribe(subscriber);

4. 事件.

    onNext():普通事件onCompleted():时间队列完结onError():时间队列异常注意:onCompleted()与onError()是互斥的,调用了其中一个另一个就不会被触发

5. Scheduler.

     - 作用:控制线程,指定某一段代码在哪个线程执行- 内置的SchedulerSchedulers.newThread(); //总是启用新线程,并在新的线程中执行操作Schedulers.io(); //I/O操作(读写文件、读写数据库、网络请求)所使用的线程。行为模式和newThread差不多,区别在于IO的内部实现的是一个无数量上线的线程池,可以重用空闲线程,因此多数情况下IO()比newThread()更有效率,不要把计算工作放在IO中,可以避免不必要的创建线程Schedulers.computation(); //计算使用的Schedulers,这个计算指的是CPU的密集型计算,既不会被I/O 等操作限制性能操作,例如图形的计算,这个Scheduler使用的固定的线程池,大小为CPU的核数。不要把IO操作放在computation()中,否则IO操作等待时间会浪费CPU.Schedulers.trampoline(); //调度器会将任务按添加顺序依次放入当前线程中等待执行(当前线程就是Schedulers.trampoline调度器创建Worker对象后,Worker对象调用scedule方法所在的线程)。线程一次只执行一个任务,其余任务排队等待,一个任务都执行完成后再开始下一个任务的执行。 Schedulers.single(); //拥有一个线程单例,所有的任务都在这一个线程中执行,当此线程中有任务执行时,其他任务将会按照先进先出的顺序依次执行。Scheduler.from(@NonNull Executor executor); //指定一个线程调度器,由此调度器来控制任务的执行策略。AndroidSchedulers.mainThread(); //在Android UI线程中执行任务,为Android开发定制。Observable.subscribeOn(); //指subscribe() 所发生的线程,即Observable.onSubscribe被激活时所处的线程。或者叫做事件产生的线程。//若多次设定,则只有一次起作用。Observable.observeOn(); //指Subscriber所运行在的线程,或者叫做事件的消费线程。(可以理解为现在要去渲染页面了,需要到主线程中去)//若多次设定,每次均起作用。

- 案例1

基本概念1-4应用遍历数组,找出数组中b开头的元素,将其转换为大写sample1:fori实现public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();String[] arr = {"shanghai", "beijing", "chengdu"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);for (int i = 0; i < arr.length ; i++) {if (arr[i].startsWith("b")){arr[i] = arr[i].toUpperCase();Log.i(TAG,arr[i]);}}}}输出结果:06-30 10:48:02.487 747-747/com.kwunyamshan.rxjava I/MainActivity: BEIJINGsample2:RxJava实现public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();String[] arr = {"shanghai", "beijing", "chengdu"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//导包不要导错 import io.reactivex.Observable;Observable<String> observable = Observable.fromArray(arr);//添加一个过滤器 , 把字母b开头的元素过滤出来Observable<String> filterObservable = observable.filter(new Predicate<String>() {@Overridepublic boolean test(String s) throws Exception {return s.startsWith("b");}});//接收结果Observer<String> observer = new Observer<String>() {@Overridepublic void onSubscribe(Disposable d) {}//真正处理事件的方法@Overridepublic void onNext(String s) {s = s.toUpperCase();Log.i(TAG, s);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}};//关联观察者与被观察者filterObservable.subscribe(observer);}输出结果:06-30 10:49:00.371 3261-3261/com.kwunyamshan.rxjava I/MainActivity: BEIJINGsample3:RxJava实现(优化)看起来sample1中的代码比sample2中的代码还要简洁,脾气暴躁的大哥就要来干我了,别急一步一步来你就明白了,下面是对RXJava进行了优化public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();String[] arr = {"shanghai", "beijing", "chengdu"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Observable.fromArray(arr)filter过滤以后返回的类型也是Observable, 所以变量可以删去,链式编程//Observable<String> filterObservable = observable.filter(new Predicate<String>() {.filter(new Predicate<String>() {@Overridepublic boolean test(String s) throws Exception {return s.startsWith("b");}})//这里如果需要做一件事则不需要new Observer,.subscribe(new Consumer<String>() {@Overridepublic void accept(String s) throws Exception {s = s.toUpperCase();Log.i(TAG, s);}});}输出结果:06-30 10:51:00.789 3261-3261/com.kwunyamshan.rxjava I/MainActivity: BEIJING你会发现这样写逻辑条理会变得特别清楚(如果会用lambda表达式的话则会更加的简洁),一个方法做一件事情,再加多少个方法逻辑也不会乱,这样写不管过了多久再回过头来看这段代码是不是也不迷糊了

- 案例2

    基本概念1-5应用获取图片,展示到ImageView上,出现异常时打印toast报错(涉及到切换线程)sample1:不考虑线程问题,简单实现1对1数据转换(关键字just)public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();private ImageView ivAvatar;private int imgId = R.mipmap.avatar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ivAvatar = findViewById(R.id.iv_avatar);//当对象是单个的时候调用justObservable.just(imgId)//将图片id转化为drawable.map(new Function<Integer, Drawable>() {@Overridepublic Drawable apply(Integer integer) throws Exception {return getResources().getDrawable(imgId);}})//把drawable设置到ImageView上.subscribe(new Consumer<Drawable>() {@Overridepublic void accept(Drawable drawable) throws Exception {ivAvatar.setImageDrawable(drawable);}});}sample2:增加线程切换,1对1数据转换(关键字just)不了解线程切换的翻回去看 5. Schedulerpublic class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();private ImageView ivAvatar;private int imgId = R.mipmap.avatar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ivAvatar = findViewById(R.id.iv_avatar);//当对象是单个的时候调用justObservable.just(imgId)//将图片id转化为drawable, 比方这个地方走网络请求图片的话这样肯定是走不成了//所以我们需要在这里添加切换线程的方法.subscribeOn(Schedulers.io())//以下代码在子线程中执行.map(new Function<Integer, Drawable>() {@Overridepublic Drawable apply(Integer integer) throws Exception {return getResources().getDrawable(imgId);}})//把drawable设置到ImageView上 , 渲染页面的逻辑在主线程中调用.observeOn(AndroidSchedulers.mainThread())//以下代码在主线程中执行.subscribe(new Observer<Drawable>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Drawable drawable) {ivAvatar.setImageDrawable(drawable);}@Overridepublic void onError(Throwable e) {Toast.makeText(MainActivity.this,e.getMessage(),1).show();}@Overridepublic void onComplete() {}});}

- 案例3

     基本概念1-5应用现在有两张表,一张单位职工表,一张职工工资表,根据职工姓名(职工表)查询职工每个月的工资(工资表)sample1:fori实现1对多查询public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SalaryBean jan = new SalaryBean("3000", 8);SalaryBean feb = new SalaryBean("3400", 9);SalaryBean mar = new SalaryBean("3000", 10);SalaryBean apr = new SalaryBean("3400", 11);SalaryBean may = new SalaryBean("5500", 12);List<SalaryBean> salaryList = new ArrayList<>();salaryList.add(jan);salaryList.add(feb);salaryList.add(mar);salaryList.add(apr);salaryList.add(may);StaffBean 秃头李 = new StaffBean("李老板", salaryList);for (int i = 0; i < 秃头李.getmSalaryList().size(); i++) {SalaryBean salaryBean = 秃头李.getmSalaryList().get(i);Log.i(TAG, "您" + salaryBean.getMonth() + "月份" + "的薪水:" + salaryBean.getSalary());}}}输出结果:06-30 10:53:48.641 8985-8985/com.kwunyamshan.rxjava I/MainActivity: 您8月份的薪水:300006-30 10:53:48.641 8985-8985/com.kwunyamshan.rxjava I/MainActivity: 您9月份的薪水:340006-30 10:53:48.641 8985-8985/com.kwunyamshan.rxjava I/MainActivity: 您10月份的薪水:300006-30 10:53:48.641 8985-8985/com.kwunyamshan.rxjava I/MainActivity: 您11月份的薪水:340006-30 10:53:48.642 8985-8985/com.kwunyamshan.rxjava I/MainActivity: 您12月份的薪水:5500sample2:用RxJava实现1对多查询(关键字flatMap)public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SalaryBean jan = new SalaryBean("3000", 8);SalaryBean feb = new SalaryBean("3400", 9);SalaryBean mar = new SalaryBean("3000", 10);SalaryBean apr = new SalaryBean("3400", 11);SalaryBean may = new SalaryBean("5500", 12);List<SalaryBean> salaryList = new ArrayList<>();salaryList.add(jan);salaryList.add(feb);salaryList.add(mar);salaryList.add(apr);salaryList.add(may);StaffBean 秃头李 = new StaffBean("李老板", salaryList);//查询单个的员工用justObservable.just(秃头李)//查询员工每个月工资情况用flatMap.flatMap(new Function<StaffBean, Observable<SalaryBean>>() {@Overridepublic Observable<SalaryBean> apply(StaffBean staffBean) throws Exception {return Observable.fromIterable(staffBean.getmSalaryList());}}).subscribe(new Consumer<SalaryBean>() {@Overridepublic void accept(SalaryBean salaryBeans) throws Exception {Log.i(TAG,  "您" + salaryBeans.getMonth() + "月份" + "的薪水:" + salaryBeans.getSalary());}});}输出结果:06-30 10:54:16.278 10183-10183/com.kwunyamshan.rxjava I/MainActivity: 您8月份的薪水:300006-30 10:54:16.278 10183-10183/com.kwunyamshan.rxjava I/MainActivity: 您9月份的薪水:340006-30 10:54:16.278 10183-10183/com.kwunyamshan.rxjava I/MainActivity: 您10月份的薪水:300006-30 10:54:16.278 10183-10183/com.kwunyamshan.rxjava I/MainActivity: 您11月份的薪水:340006-30 10:54:16.278 10183-10183/com.kwunyamshan.rxjava I/MainActivity: 您12月份的薪水:5500

案例下载传送门

RxJava2.x的集成及用法详解相关推荐

  1. STL中map和string, vector 用法详解

    1. map 用法详解 std map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成 ...

  2. idea2019配置gradle详解_Constraint Layout 2.0 用法详解

    Constraint Layout 是最受欢迎的 Jetpack 库之一,它的 2.0 正式版本也发布啦 (目前最新版本 2.1.0-alpha1)!也许您已熟悉了 Constraint Layout ...

  3. Python中第三方库Requests库的高级用法详解

    Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...

  4. C语言高频率--typedef和const用法详解

    一.typedef用法详解 C语言允许为一个数据类型起一个新的别名,就像给人起"绰号"一样. 起别名的目的不是为了提高程序运行效率,而是为了编码方便.例如有一个结构体的名字是 st ...

  5. 转: std::string用法详解

    原文地址为: 转: std::string用法详解  C++中的string 类 简单介绍 前言: string 的角色 1 string 使用 1.1 充分使用string 操作符 1.2 眼花缭乱 ...

  6. nodejs java rsa_NodeJS加密解密及node-rsa加密解密用法详解

    要用nodejs开发接口,实现远程调用,如果裸奔太危险了,就在网上找了一下nodejs的加密,感觉node-rsa挺不错的,下面来总结一下简单的rsa加密解密用法 初始化环境 新建一个文件夹 node ...

  7. [网络安全提高篇] 一一九.恶意软件动态分析经典沙箱Cape的安装和基础用法详解

    终于忙完初稿,开心地写一篇博客. "网络安全提高班"新的100篇文章即将开启,包括Web渗透.内网渗透.靶场搭建.CVE复现.攻击溯源.实战及CTF总结,它将更加聚焦,更加深入,也 ...

  8. python decode函数的用法_Oracle DECODE函数的用法详解

    Oracle DECODE函数 使用方法: 1.比较大小 select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值 sign()函数根据某个值 ...

  9. Constraint Layout 2.0 用法详解

    Constraint Layout 是最受欢迎的 Jetpack 库之一,它的 2.0 正式版本也发布啦 (目前最新版本 2.1.0-alpha1)!也许您已熟悉了 Constraint Layout ...

最新文章

  1. 如何设计电桥传感器驱动电路?
  2. 【FFmpeg】详解FFmpeg解封装、解码流程
  3. 多线程(十、AQS原理-ReentrantLock公平锁)
  4. Java并发基础构建模块简介
  5. 基于CentOS 6.8平台最新源代码包编译安装企业版MariaDB数据库
  6. EPUB.js 解决图片裁剪问题(缩放问题)
  7. 关于本地共享文件夹会话连接时间
  8. Arrays.hashCode(Object [])与Objects.hash(Object…)
  9. 面试官系统精讲Java源码及大厂真题 - 09 TreeMap 和 LinkedHashMap 核心源码解析
  10. IAR下μCosIII移植心得
  11. 鸿蒙应用开发--组件
  12. sign签名算法一致算法-.net、java、golang
  13. 洛谷 P1017 进制转换
  14. 微信小程序人脸识别获取照片,并解决相机拍照在ios上有声音问题
  15. autojs颜色渐变效果
  16. 长江大学计算机基础试卷2018 2019,长江大学2017年第一学期-计算机基础试卷.doc
  17. 环网交换机的主要作用是什么?
  18. 超级炫酷的3D旋转美女图——Python实现
  19. 上海法官招嫖爆料者讲述始末
  20. dpdk 多进程共享内存描述信息的机制

热门文章

  1. 韦一之内存控制器,2440地址空间,NOR flash和SDRAM(012课)
  2. JSP+Servlet制作简易计算器
  3. 数据库期末复习题总汇
  4. Kafka异常问题记录
  5. Fmoc-Lys (biotin-PEG4)-OH,1334172-64-3生物素标记的、基于PEG的PROTAC连接物
  6. mall在Linux环境下的部署(基于Docker容器)
  7. 安卓手机改机 抹机 硬改手机参数 手机 改串 改机器内存存储信息 虎贲T610 机器演示
  8. 关于ChatGPT的一些小问题
  9. 《ES6》(阮一峰)学习笔记
  10. 前端:你可能不知道的骨架屏方案设计