响应式编程
什么是响应式编程
通过异步和数据流来构建事务关系的编程模型
举例
app启动时, 先初始化sdk, 初始化数据库, 登录, 都成功后跳转首页, 他们都需要耗时操作
Observable.just(context)
.map((context)->{login(getUserId(context))})
.map((context)->{initSDK(context)})
.map((context)->{initDatabase(context)})
.subscribeOn(Schedulers.newThread())
.subscribe((context)->{startActivity()})
复制代码
- 其实,这种写法并不是响应式的,本质上还是创建一个子线程,然后顺序调用代码最后跳转页面。这种代码依然没有忠实反映业务之间的关系
Observable obserInitSDK=Observable.create((context)->{ initSDK(context) }).subscribeOn(Schedulers.newThread())
Observable obserInitDB=Observable.create((context)->{ initDatabase(context) }).subscribeOn(Schedulers.newThread())
Observable obserLogin=Observable.create((context)->{ login(getUserId(context)) })
.map((isLogin)->{ return Context() })
.subscribeOn(Schedulers.newThread())
Observable observable = Observable.merge(obserInitSDK,obserInitDB,obserLogin)
observable.subscribe(()->{startActivity()})
复制代码
- 大家应该能很明显看到两段代码的区别,第二段代码完全遵照了业务之间客观存在的关系,可以说代码和业务关系是完全对应的。
- 那么这带来了什么好处呢?当initSDK,initDB,Login都是耗时较长的操作时,遵照业务关系编写响应式代码可以极大的提高程序的执行效率,降低阻塞。
- 理论上讲,遵照业务关系运行的代码在执行效率上是最优的
RxJava常用用法
创建被观察者的几种方式
//1
Observable switcher = Observable.create(new Observable.OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("On");
subscriber.onCompleted();
}
});
//2
Observable switche r= Observable.just("On","Off","On","On");
//3
String [] kk={"On","Off","On","On"};
Observable switcher = Observable.from(kk);
复制代码
创建观察者的几种方式
//1
Subscriber light = new Subscriber<String>() {
@Override
public void onCompleted() {
//被观察者的onCompleted()事件会走到这里;
Log.d("DDDDDD","结束观察...\n");
}
@Override
public void onError(Throwable e) {
//出现错误会调用这个方法
}
@Override
public void onNext(String s) {
//处理传过来的onNext事件
Log.d("DDDDD","handle this---"+s)
}
//2 偷懒(非正式写法)
Action1 light = new Action1<String>() {
@Override
public void call(String s) {
Log.d("DDDDD","handle this---"+s)
}
}
复制代码
将两者订阅在一起
switcher.subscribe(light);
复制代码
之所以“开关订阅台灯”, 是为了保证流式API调用风格
RxJava常用操作符
Map类型变换
Observable.just(getFilePath()
.subscribeOn(Schedulers.newThread()) //指定了被观察者执行的线程环境
.observeOn(Schedulers.io()) //将接下来执行的线程环境指定为io线程
//使用map操作来完成类型转换
.map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return createBitmapFromPath(s); //方法,是一个极其耗时的操作
}
})
.observeOn(AndroidSchedulers.mainThread()) //将后面执行的线程环境切换为主线程
.subscribe(
new Subscriber<Bitmap>() { //创建观察者,作为事件传递的终点处理事件
@Override
public void onNext(Bitmap s) {
showBitmap(s) //处理事件
}
);
复制代码
FlatMap
//创建被观察者,获取所有班级
Observable.from(getSchoolClasses())
.flatMap(new Func1<SingleClass, Observable<Student>>() {
@Override
public Observable<Student> call(SingleClass singleClass) {
//将每个班级的所有学生作为一列表包装成一列Observable<Student>,将学生一个一个传递出去
return Observable.from(singleClass.getStudents()); //返回Observable
}
})
.subscribe(
//创建观察者,作为事件传递的终点处理事件
new Subscriber<Student>() {
@Override
public void onNext(Student student) {
//接受到每个学生类
Log.d("DDDDDD",student.getName())
}
);
复制代码
FlatMap可以再次包装新的Observable,而每个Observable都可以使用from(T[])方法来创建自己
粘性事件:就是可以接收订阅之前的事件
ViewMode+LiveData 模式
编译原理,数据结构,操作系统,计算机组成原理
KMP算法