操作符是用来干什么的?Rxjava中的每一个操作符基本都是用来创建Observable,也就是被订阅者。RxJava中常用的操作符包括:创建操作符,连接操作符,工具操作符,变换操作符,过滤操作符,条件操作符,布尔操作符,合并操作符。本次着重了解创建操作符的用法。

创建操作符

10种常用的操作符定义

摘自《RxJava实战》


just:将一个或多个对象转换成发射这个或这些对象的一个Observable; from:将一个Interable,一个Future或者一个数组转换成一个Observable; create:使用一个函数从头创建一个Observable; defer:只有当订阅者订阅才创建Observable,为每个订阅创建一个新的Observable; range:创建一个发射指定范围的整数序列的Observable; interval:创建一个按照给定的时间间隔发射整数序列的Observable; timer:创建一个在给定的延时之后发射单个数据的Observable; empty:创建一个什么都不做直接通知完成的Observable; error:创建一个什么都不做直接通知错误的Observable; never:创建一个不发射任何数据的Observable。

下面做几个操作符的demo演示

create

此处模拟create中报错的场景


Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> observableEmitter) throws Exception {
try {
if (!observableEmitter.isDisposed()) {
for (int i = 0; i < 10; i ++) {
observableEmitter.onNext(i);
String str = null;
str.length();
}
observableEmitter.onComplete();
}
} catch (Exception e) {
observableEmitter.onError(e);
} }
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("Next: " + integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("Error: " + throwable.getMessage());
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("Sequence complete. ");
}
});

运行结果:

just就不写了,之前写hello world的时候就用过了。

from

发射Iterable或者数组的每一项数据


Observable.fromArray("hello", "from").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});

运行结果:

repeat

重复的发射原始Observable的数据序列,次数通过repeat(n)指定


Observable.just("hello repeat")
.repeat(3)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});

运行结果:

defer

这里我们在observable订阅前睡眠1秒,我们发现只有当observable被订阅了,发射的“hello defer”这条消息才被打印出来

Observable observable = Observable.defer(new Callable<ObservableSource<?>>() {
@Override
public ObservableSource<?> call() throws Exception {
return Observable.just("hello defer");
}
});
TimeUnit.SECONDS.sleep(1);
observable.subscribe(new Consumer<String>() {
@Override
public void accept(String str) throws Exception {
System.out.println(str);
}
});

运行结果:

interval

interval是按照固定的时间发射一个无限递增的整数序列

Observable.interval(1, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
});
TimeUnit.SECONDS.sleep(10);

运行结果:

Scheduler

什么是RxJava线程?RxJava是一个为异步线程而实现的库,所以RxJava的特点就是异步,一个通过异步编程合理提高系统处理速度的。在默认情况下,RxJava是单线程的。用Observable发射数据,Observe接受和响应数据,各种操作符来加工处理数据流,都是在同一个线程中运行的,实现出来的就是一个同步的函数响应式。其实在Observer中接受和响应数据会牵涉到多线程来操作RxJava,这些多线程我们通过调度器(Scheduler)来实现。上述总结于《RxJava实战》这本书中。

什么是Scheduler?

Scheduler是RxJava对线程控制器的一个抽象,RxJava内置了多个Scheduler的实现。常用的调度器有single,newThread,computation,io,trampoline,Schedulers.from这五个。当然如果自带的调度器不能满足需求,我们是可以自己定义Executor来作为调度器的。

如何使用Scheduler

  • 切换newThread线程
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("hello");
observableEmitter.onNext("world");
}
}).observeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
  • 线程调度的两种方法,也就是线程的切换
通过observeOn或者subscribeOn方法
Observable.just("hello", "world")
.observeOn(Schedulers.newThread())
.map(new Function<String, String>() {
@Override
public String apply(@NonNull String s) throws Exception {
return s.toUpperCase();
}
})
.subscribeOn(Schedulers.single())
.observeOn(Schedulers.io())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});

不同线程调度器的使用场景

  • computation()
用于CPU密集型的计算任务,不适合I/O操作
  • io()
用于I/O密集型任务,支持异步阻塞I/O操作,这个调度器的线程池会根据需要增长,对于普通的计算任务,还是用Schedulers.computation()
  • newThread()
为每个任务创建一个新的线程。
  • single()
single拥有一个线程单例,所有的任务都在这一个线程中执行,当此线程中有任务执行时,它的任务将会按照先进先出的顺序依次执行。
  • 几种线程测试demo
Map map = new HashMap();
Observable.just("hello world")
.subscribeOn(Schedulers.single())
.map(new Function<String, String>() {
@Override
public String apply(@NonNull String s) throws Exception {
s = s.toUpperCase();
map.put("map1", s);
return s;
}
})
.observeOn(Schedulers.io())
.map(new Function<String, String>() {
@Override
public String apply(@NonNull String s) throws Exception {
s = s + " leo.";
map.put("map2", s);
return s;
}
})
.subscribeOn(Schedulers.computation())
.map(new Function<String, String>() {
@Override
public String apply(@NonNull String s) throws Exception {
s = s + "it is a test";
map.put("map3", s);
return s;
}
})
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
map.put("subscribe", s);
System.out.println(s);
}
});

总结:操作符,线程操作的使用,大家可以多看看相关书籍,自己多敲代码,带着不懂去看源码或者相关文档,作为初学者,现在也只是看着书上的皮毛,自己敲着书上的demo来理解。学习之路慢慢,共勉。。。

Rxjava - 操作符,线程操作的简单使用的更多相关文章

  1. Rxjava2实战--第四章 Rxjava的线程操作

    Rxjava2实战--第四章 Rxjava的线程操作 1 调度器(Scheduler)种类 1.1 RxJava线程介绍 默认情况下, 1.2 Scheduler Sheduler 作用 single ...

  2. RxJava 操作符 on和doOn 线程切换 调度 Schedulers 线程池 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. C#跨线程操作控件的最简单实现探究

    随着程序复杂度的提高,程序不可避免会出现多个线程,此时就很可能存在跨线程操作控件的问题. 跨线程操作UI控件主要有三类方式: 1.禁止系统的线程间操作检查.(此法不建议使用) 2.使用Invoke(同 ...

  4. RxJava操作符实践:8_算术和聚合操作之3_min

    发射原始Observable的最小值. Min操作符操作一个发射数值的Observable并发射单个值:最小的那个值. RxJava中,min属于rxjava-math模块. min接受一个可选参数, ...

  5. winform 跨线程操作控件

    当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...

  6. iOS子线程操作UI问题检查

    iOS开发中,因为大部分函数都不是线程安全的,所以UI子线程中操作UI是非常危险的事,但是有时候因为开发者经验不足,不知道子线程中不能UI,或者知道但是写代码的时候没注意,或者不知道那些函数操作UI了 ...

  7. Redis:安装、配置、操作和简单代码实例(C语言Client端)

    Redis:安装.配置.操作和简单代码实例(C语言Client端) - hj19870806的专栏 - 博客频道 - CSDN.NET Redis:安装.配置.操作和简单代码实例(C语言Client端 ...

  8. PyQt5 QSerialPort子线程操作

    环境: python3.6 pyqt5 只是简单的一个思路,请忽略脆弱的异常防护: # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets im ...

  9. 理解 RxJava 的线程模型

    来源:鸟窝, colobu.com/2016/07/25/understanding-rxjava-thread-model/ 如有好文章投稿,请点击 → 这里了解详情 ReactiveX是React ...

随机推荐

  1. Git忽略提交 .gitignore配置。自动生成IDE的.gitignore。解决gitignore不生效

    语法 以”#”号开头表示注释: 以斜杠“/”开头表示目录: 以星号“*”通配多个字符: 以问号“?”通配单个字符 以方括号“[]”包含单个字符的匹配列表: 以叹号“!”表示不忽略(跟踪)匹配到的文件或 ...

  2. select 下拉框 disabled 则 Form 获取不到值

    select 下拉框 disabled 则 Form 获取不到值 有时候需要禁用 下拉框 , 但是表单又需要获取到 下拉框的值. 解决方案1: 使用文本框和隐藏域 来代替下拉框 disabled 解决 ...

  3. 在.NET中操作数字证书(新手教程)

    .NET为我们提供了操作数字证书的两个主要的类,分为为: System.Security.Cryptography.X509Certificates.X509Certificate2类, 每个这个类的 ...

  4. libextobjc 实现的 defer

    算法沉思录:分而治之(复用): 分而治之是指把大而复杂的问题分解成若干个简单的小问题,然后逐个解决.这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域. 要崩溃的节奏: 要崩溃的节奏: V ...

  5. java面向切面编程总结-面向切面的本质

    面向切面的本质:定义切面类并将切面类的功能织入到目标类中: 实现方式:将切面应用到目标对象从而创建一个新的代理对象的过程.替换: 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Point ...

  6. Payment:微信支付配置文件设置说明

    项目GitHub地址:https://github.com/helei112g/payment 微信支付个人觉得在帐号设置上有些麻烦,帐号太多啦,支付宝目前就是一个应用基本涵盖了所有的接口开发. 可能 ...

  7. 20155314 2016-2017-2 《Java程序设计》第1周学习总结

    20155314 2016-2017-2 <Java程序设计>第1周学习总结 学习目标 了解Java基础知识(已完成) 了解JVM.JRE与JDK,并下载.安装.测试JDK(已完成) 了解 ...

  8. 20145203盖泽双 《Java程序设计》第四周学习总结

    20145203盖泽双 <Java程序设计>第四周学习总结 教材学习内容总结 1.多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单 ...

  9. C语言偏冷知识点汇总

    1.C语言函数声明中参数类型写在右括号后是什么意思?如下代码所示: int add(a, b) int a; int b; { return a + b; } 像这样的声明是什么意思,我测试过在gcc ...

  10. Google 地图切片URL地址解析

    一.Google地图切片的投影方式及瓦片索引机制 1.地图投影 Google地图采用的是Web墨卡托投影(如下图),为了方便忽略了两极变形较大的地区,把世界地图做成了一个边长等于赤道周长的正方形(赤道 ...