今天 17:00前完成
先坚定信心,告诉自己,一定要学会 RxJava
学习讲究条件,客观 + 主观,客观方面我们要善于借助 有利条件(比如官方文档等),主观就是要告诉自己,做学问不能浮躁,要静下心来,方可致远。
约定
因为这里会出现一些抽象名词,我想通过语言的不恰当比喻,对这些词语换一个说法,以便于理解
观察者 —— 摄影师
被观察者 —— 模特
被观察者行为 —— 通知观察者你可以搞事情了,简言之:通知
观察者行为 —— 根据被观察者通知去搞事情,简言之:搞
引言——观察者模式
1 简要说明:观察者对被观察者的某种变化高度敏感,需要在 B 变化的一瞬间作出响应。
2 实现方式
2.1 低效的实现方式
摄影师每过2s就问一下模特美美可以拍照了吗
2.2 高效的实现方式
模特每摆好一个POS,就告诉摄影师哥哥可以拍照了
这里请允许我唠叨一会儿,他们之间的关系是摄影师观察模特美美,然而实际的行为是模特美美摆好Pos后通知摄影师你可以搞我了,快点别墨迹,赶快来搞我,然而摄影师得到这个通知后,就开始真正的去搞这个妹妹,实际上也就是拍个照片,大家别想歪哦
RxJava 的观察者模式
Observer —— 摄影师
Observable —— 美美
被观察者行为 —— 通知摄影师搞事情、通知摄影师搞错了、通知摄影师搞完了
观察者行为 —— 搞事情、搞错了、搞完了
RxJava 观察者模式基本实现
package liujinliang.natappvip.cc.rxwrapperdemo;
import org.junit.Before;
import org.junit.Test;
import rx.Observable;
import rx.Subscriber;
import rx.observers.Subscribers;
public class RxJavaTest {
@Before
public void printPre() {
Thread.currentThread().setName("currentThread");
}
@Test
public void testSubscribe() {
// 摄影师
final Subscriber<String> subscriber =
new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("onCompleted in tread:" +
Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("onError in tread:" +
Thread.currentThread().getName());
e.printStackTrace();
}
@Override
public void onNext(String s) {
System.out.println("onNext in tread:" +
Thread.currentThread().getName());
System.out.println(s);
}
};
// 美美
Observable observable = Observable.create(
new Observable.OnSubscribe<Subscriber>() {
@Override
public void call(Subscriber subscriber1) {
// 发生事件
System.out.println("call in tread:" + Thread.currentThread().getName());
subscriber1.onStart();
//subscriber1.onError(new Exception("error"));
subscriber1.onNext("hello world");
subscriber1.onCompleted();
}
}
);
// 通知
observable.subscribe(subscriber);
}
@Test
public void testScheduler() {
}
@Test
public void testMap() {
}
}
只是搞一下,没必要让摄影师亲自出马吧
Action1<String> onNextAction = new Action1<String>() {
// onNext() 有参数无返回值
@Override
public void call(String s) {
Log.d(tag, s);
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
// onError() 有参数无返回值
@Override
public void call(Throwable throwable) {
// Error handling
}
};
Action0 onCompletedAction = new Action0() {
// onCompleted() 无参数无返回值
@Override
public void call() {
Log.d(tag, "completed");
}
};
// 自动创建 Subscriber ,并使用 onNextAction 来定义 onNext()
observable.subscribe(onNextAction);
// 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
我们接下来可以看一下 RxJava 的线程控制了
1 先来学习一下RxJava下的线程有哪些喽
1.1 Scheduler.immediate() 当前线程(默认)
1.2 Scheduler.io() 用于存储、网络请求的线程(本质是由一个无上限、可重复利用的线程池管理)
1.3 Scheduler.computation() 用于计算的线程,比如说图形计算问题
1.4 Scheduler.mainThread() 主线程(也就是我们的 UI 线程)
2 再来看一个小例子
@Test
public void testScheduler() {
//观察者/订阅者
final Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("onCompleted in tread:" +
Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("onError in tread:" +
Thread.currentThread().getName());
e.printStackTrace();
}
@Override
public void onNext(String s) {
System.out.println("onNext in tread:" +
Thread.currentThread().getName());
System.out.println(s);
}
};
//被观察者
Observable observable = Observable.create(
new Observable.OnSubscribe<Subscriber>() {
@Override
public void call(Subscriber subscriber1) {
// 发生事件
System.out.println("call in tread:" +
Thread.currentThread().getName());
subscriber1.onStart();
subscriber1.onNext("hello world");
subscriber1.onCompleted();
}
});
//订阅
observable.subscribeOn(Schedulers.io()) // 指定生产事件在io线程中进行
.observeOn(Schedulers.newThread()) // 指定消费事件在新线程中进行
.subscribe(subscriber);
}
输出结果
call in tread:RxCachedThreadScheduler-1
onNext in tread:RxNewThreadScheduler-1
hello world
onCompleted in tread:RxNewThreadScheduler-1
在这里我们先暂停一下,因为我打算上一个图,因为我们现在所做的事情已经可以解释这张图的一些行为了,在这里,我只解释了两个箭头而已,以橘黄色标出了这两个箭头其实代表的是线程,名字也标注在了图中
那么接下来我们就可以看一下这张图里面的小圆点了
先打个预防针,这些小圆点就代表的是数据,从紫色变到蓝色,我们可以直观的理解为,数据从紫色状态变到了蓝色状态,
那么他们是怎么从一个状态变换到另一个状态呢,这就是RxJava操作符的作用了,我们先看一下图解,再看一下代码。
1 官方图解
2 示例代码
主要说明一下map干了个什么事情,将某一类型的事件变量变换为另一类型的事件变量,下面的例子map主要做了一件事情,就是对象的类型变换:字符串变成了User对象,又把User对象变成了Object对象
// map
@Test
public void testMap() {
String name = "Gene";
Observable.just(name)
.subscribeOn(Schedulers.newThread()) // 指定下一个生成节点在新线程中处理
.map(new Func1<String, User>() {
@Override
public User call(String name) {
User user = new User();
user.setName(name);
System.out.println("process User call in tread:"
+ Thread.currentThread().getName());
return user;
}
})
.subscribeOn(Schedulers.newThread()) // 指定下一个生成节点在新线程中处理
.map(new Func1<User, Object>() {
@Override
public Object call(User user) {
// 如果需要,我们在这里还可以对 User 进行加工
System.out.println("process User call in tread:"
+ Thread.currentThread().getName());
return user;
}
})
.observeOn(Schedulers.newThread()) // 指定消费节点在新线程中处理
.subscribe(new Action1<Object>() {
@Override
public void call(Object data) {
System.out.println("receive User call in tread:"
+ Thread.currentThread().getName());
}
});
}
public static class User {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}