RxJava学习笔记(一)概念
来源:互联网 发布:vb和java哪个好 编辑:程序博客网 时间:2024/06/04 18:10
RxJava 学习笔记(一)概念
Rxjava 从去年开始就有耳闻,在各大开源项目中也可以看到有使用他的,各大牛也说他好用,既然大家都说好,具体好不好我们自己学着用一下就知道了,刚好这段时间项目闲下来就来学习一下RxJava。
1 是什么
同样,在用一个东西之前,要先知道他是什么东西。
“RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.”
这句话说得很全面了,RxJava是一个在Java虚拟机上的Reactive扩展程序:在Java虚拟机上使用可观测的序列来组成异步的,基于事件的程序的库。
简单来说:RxJava 是一个库,本质是异步
附上主页地址:https://github.com/ReactiveX/RxJava
2 可以做什么
2.1 简化逻辑、异步操作
举个栗子,有若干名学生,现在想要打印出每一个学生的所有科目成绩。你可能会想到这样写:
//for 循环private void demo7_1(List<StudentBean> students) { for (StudentBean studentBean : students) { Log.d("demo7_1", "姓名:" + studentBean.getName()); for (Cause cause : studentBean.getCauseList()) { Log.d("demo7_1", formatCause(cause)); } }}private String formatCause(Cause cause) { return String.format("caseName:%s->>causeGrade:%s", cause.getName(), cause.getGrade());}
这样当然OK,如果我还要加一个条件,打印出每一个男学生的所有科目成绩。你是不是又想用到一层循环了。在比如我学生量超大,你是不是还想到了不能在主线程操作了?写过大项目都知道迷之循环谜之缩进毁一生。逻辑不多的情况没有影响,一旦逻辑多起来你可能都不知道自己写的是什么。
我们再来看一下用RxJava如何解决这个问题
//RxJavaprivate void demo7_2(List<StudentBean> students) { from(students).subscribe(new Action1<StudentBean>() { @Override public void call(StudentBean studentBean) { Log.d("demo7_2", "姓名:" + studentBean.getName()); for (Cause cause : studentBean.getCauseList()) { Log.d("demo7_2", formatCause(cause)); } } });}
先简单说一下操作符,from可以把传入的集合依次遍历输出,后面还会专门讲操作符,不要急。action1是RxJava的一个接口,call(T param),先简单理解为一个处理结果的回调。
当然你们会说不就用一个from代替了一层循环吗?并没有什么卵用,还不是内部有一个for循环,当然我们可以更优雅一点。
private void demo7_3(List<StudentBean> students) { from(students).map(new Func1<StudentBean, List<Cause>>() { @Override public List<Cause> call(StudentBean studentBean) { Log.d("demo7_3", "姓名:" + studentBean.getName()); return studentBean.getCauseList(); } }).subscribe(new Action1<List<Cause>>() { @Override public void call(List<Cause> causes) { for (Cause cause : causes) { Log.d("demo7_3", formatCause(cause)); } } });}
有好事的(就是我)又说在用一个from不可以吗?反正都是遍历。当然可以,但是就不能保证一个流式了,map里原理其实也是这样,但是千万不要把map理解为又是一个from,后面单独有一章将变换。
在加上我们刚才说的逻辑,打印性别为男的,新开线程中运行。
private void demo7_4(List<StudentBean> students) { from(students)//遍历学生数组 .subscribeOn(Schedulers.io())//在IO线程中运算 .observeOn(AndroidSchedulers.mainThread())//在主线程中回调 .filter(new Func1<StudentBean, Boolean>() { @Override public Boolean call(StudentBean studentBean) { return studentBean.isMale();//筛选出性别为男的数据 } }) .map(new Func1<StudentBean, List<Cause>>() { @Override public List<Cause> call(StudentBean studentBean) { Log.d("demo7_4", "姓名:" + studentBean.getName() + "性别:" + (studentBean.isMale() ? "男" : "女")); return studentBean.getCauseList(); } }) .subscribe(new Action1<List<Cause>>() { @Override public void call(List<Cause> causes) { for (Cause cause : causes) { Log.d("demo7_4", formatCause(cause)); } } });}
有人会说,这简单个屁啊,代码量变多了,我还看不懂了!您消消气,我开始也说了是逻辑的简化,在看一下注释,是不是都在一条调用链上一路“.”下来的,每一步做的什么一目了然是不?如果项目放在那大半年在突然让你去加个功能,这样看起来逻辑梳理的要快得多。
来解释一下:
Scheduler 的API
subscribeOn(Scheduler scheduler)
决定了subscribe() 之前的程序运行在哪个线程中,我们叫事件产生的线程,主要有:
io()指 I\O线程,用于一些读写操作,例如查找数据库,网络请求,内部是无上限的线程池;
computation() 计算线程,用于处理一些CPU密集计算,内部是核数的线程池;
newThread() 新起一个线程;
immediate() 当前线程,也是默认值;
AndroidSchedulers.mainThread(),Android主线程即UI线程,使用这个需要额外添加一个依赖
compile 'io.reactivex:rxandroid:1.0.1'
observeOn(Scheduler scheduler)
决定了subscribe()响应在哪个线程,我们叫事件消费的线程,通常用于做一些耗时操作之后更新UI的一些动作,就类似Handler 消息机制,主要的Scheduler也和上面的一致。
又有好事的问了,能不能多切换几次,答案是可以!but,subscribeOn以第一次出现的为准;observeOn以最后一次出现的为准!
关于Scheduler的线程切换原理我们之后在说,在这之前还需要来了解一些其他的知识。
3 怎么使用
看完刚那个例子我们已经大致了解到RxJava 的一些优势了,好就好在能把好多复杂的逻辑都穿成一条线,并且还能异步操作。
RxJava的API比较多,操作符也比较多,在学习API和操作符,在穿插一些原理分析,自然就知道怎么用了。
3.1 API介绍及原理分析
1) 概念 观察者模式
链接里是鸿洋大神的透彻分析,我这里就简单说一下自己的学习理解。
还是举个栗子:虚拟机告诉代码“你在出异常的时候和我说一下”。
这个例子里面,”虚拟机”是观察者,”代码”是被观察者,”告诉”是关联关系在代码出错的时候虚拟机会做相应的动作。
那么我们知道观察者模式有两个实体一个关系:
1. 观察者 Observer
被观察者 Observable
订阅关系 subscribe
在举一个开发中的例子:
View.OnClickListener observer = new View.OnClickListener() { @Override public void onClick(View v) { Log.d("webber","点击了!"); } }; mLoginBt.setOnClickListener(observer);
这里我故意把Listener起名为observer,方便理解,在这个例子中mLoginBt这个View是被观察者,observer这个监听器是观察者,他们通过setOnClickListener关联起来,observer就能在View被点击的时候收到通知。
这个概念抽象出来就是
Button(被观察者);onClick(事件);Listener(观察者)
图片出自给 Android 开发者的 RxJava 详解,感谢扔物线大神。
2)基本实现
Ok,在了解基本概念之后我们要开始使用这个工具了!我们知道需要有观察者、被观察者、关联关系
创建Observer
//创建观察者Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { Log.d("webber", "onCompleted:"); } @Override public void onError(Throwable e) { Log.d("webber", "onError:" + e.getMessage()); } @Override public void onNext(String s) { Log.d("webber", "onNext:" + s); }};
创建Observable
//创建被观察者 Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { //subscriber.onStart(); Log.d("network", "call" + Thread.currentThread().getName()); subscriber.onNext("item1"); subscriber.onNext("item2"); subscriber.onNext("item3"); subscriber.onCompleted(); //subscriber.onError(new Throwable("我出错了!!!")); } });
3.关联关系
observable.subscribe(observable);
有些细心的可能会发现不是应该观察者订阅被观察者吗,这里为什么反了?
这就有点像是杂志订阅了读者。但是如果颠倒一下关系就会影响整个流式布局,得不偿失。
概念先说到这,下一章介绍Rxjava中的一些常见操作符及示例。
代码已经上传:https://github.com/ieewbbwe/RxJavaSamples
第一次写有点乱,欢迎大家批评建议!
- RxJava学习笔记(一)概念
- RxJava 学习笔记(一)
- RxJava学习笔记(一)
- RxJava学习笔记(一)
- RxJava 学习笔记一
- RxJAVA学习笔记(一)
- Rxjava学习笔记(一)
- Rxjava学习笔记(一)
- RxJava学习笔记(一)--- 基础篇
- RxJava学习笔记之初识(一)
- RxJava 2.x 学习(一)基础概念
- RxJava 学习(一)
- RxJava学习(一)
- RXjava学习(一)
- Rxjava学习(一)
- RxJava学习(一),RxJava初识
- PowerShell学习笔记(一) 初步概念
- Portal学习笔记(一) 概念
- 人生,贵在坚持
- 第13周项目2-Kruskal算法的验证
- 关于MediaRouter的理解
- 每天学习opensatck(1)
- Oracle Database之表基本操作(DDL)
- RxJava学习笔记(一)概念
- 我的语境对member variable,property,attribute的翻译
- Java 字符串和字符串缓冲区的常用方法
- android 中 dumpsys 命令使用
- 2.3Loader
- CSS语法规范!!!!!!!!!!!!!!!!!!!!!!!
- 05-树9 File Transfer
- 学习SQL数据查询地址
- 巧妙的字符串排序,保证你不看,绝对想不到