Rjava 从入门到开发
rxjava在业内越来越受欢迎,但是虽受欢迎却难理解,辛亏前面有大神们开路,并把心得体会记录流传后辈。比较出名的有抛物线,hi大头鬼等等,当时拜读大神们的文章,感受颇多,最深的体会是:虽得武林绝学,但无奈本人内力不足,学完秘籍还是觉得似懂非懂,得此招数,却无法理解精髓。但是经过一段时间的摸索,也慢慢有了一些对学习rxjava的心得体会,故记录下来充当自己的笔记,也希望可以给想学习rxjava的童鞋一些学习的思路。本篇文章主要分为两大部分:(1)如何学习rxjava(2)rxjava实战案例
一、如何学习rxjava
如何学习rxjava,个人觉得可以从以下几个方面学习:
(1)使用rxjava的好处
随着项目功能增多,代码量会慢慢增加,复杂度也会加强,学习rxjava可以帮助我们:
- 规范项目成员的代码实现
- 让复杂的逻辑变得有条理性
通过以上两点可以规范团队的编码习惯提高效率,另外也方便我们定位问题,解决问题。在这里多说一句关于提高效率的问题,如何可以提高编码效率呢,个人觉得定好编码规范,另外写好代码架构非常重要,目前也出现了一些mvp,flux等等模式帮助我们定好项目规范。
(2)了解rxjava的基本元素
rxjava的基本三要素如下:
- Observable:被观察者
- Subscriber:观察者
- OnSubscribe:一个接口类,是连接被观察者和观察者的桥梁,另外要说明的是onSubscribe是Observable的一个局部变量
上面这样官方的概念其实不容易理解:sweat_smile:,如何简单理解上面这“吉祥三宝”呢,本人是这么理解的,举个具体例子:造一辆小车,造小车的过程可以分为一道道连续的工序,简单来说就是:步骤一(造底盘),步骤二(加上轮子)等等,那么:
Observable:处理步骤一,步骤二等等操作的分别对应的“工厂一”,“工厂二”等等。
OnSubscribe:“工厂一”对应的“车间一”,“工厂二”对应的“车间二”
Subscriber:获取汽车成品的地方。
我们可以把一个任务拆分成为一个个依次执行的子任务,这种条理性也就是rxjava好用的地方。
(3)rxjava的操作符使用
在(1)(2)节中我大概介绍了rxjava的概念,让大家对rxjava有个感性的认识,但真正想学习rxjava还得从学习操作符开始,那么什么是操作符?简单来说: 操作符就是Observable的各种操作,例如:创建,变换,过滤操作等等 。在这里需要强调下的是,Observable通过操作符的操作之后会得到一个 新的Observable ,每创建一个操作符,简单来说就是创建了一个子任务,这个在后面源码分析会讲到,这里就不细讲了。
举个创建操作符 Create 的代码例子:代码结果很简单,依次输出“0,1,2”三个数,最后输出“hello rxjava execute complete”这句话。
Observable.create(new Observable.OnSubscribe(){ @Override public void call(Subscriber subscriber) { for(int i=0;i执行for循环-->通过call(Subscriber subscriber)传入的subscriber发送结果-->Subscriber的onNext等方法中订阅想要的结果。### 2.操作符map与“吉祥三宝”的关系根据上面案例,我们发现通过create操作符完成一次操作就涉及到”吉祥三宝“调用一次了,姑且用Observable0,Subscriber0,OnSubscribe0表示,那么通过create和map一起调用的话和”吉祥三宝“的联系又是怎样的呢,答案是map操作也涉及了"吉祥三宝",暂时可以用Observable1,Subscriber1,OnSubscribe1来表示。
Observable.create(new Observable.OnSubscribe(){
@Override public void call(Subscriber subscriber) { for(int i=0;i 图中共有 5 处含有对事件的操作。由图中可以看出,①和②两处受第一个 subscribeOn()影响,运行在红色线程;③和④处受第一个observeOn()的影响,运行在绿色线程;⑤处受第二个 onserveOn()影响,运行在紫色线程;而第二个 subscribeOn(),由于在通知过程中线程就被第一个 subscribeOn()截断,因此对整个流程并没有任何影响。这里也就回答了前面的问题:当使用了多个subscribeOn()的时候,只有第一个 subscribeOn()起作用。
最后再总结一下操作符和和线程调度。。 把一个大功能通过不同的操作符依次分为一道道小工序,工序加工可以通过调度器指定在什么线程池执行,这个过程就是rxjava的作用,这种条理性就是rxjava的魅力所在。
二、rxjava实战案例
上面说了那么多,还是用一些在Android项目中遇到的案例给大家演示下rxjava的作用吧。
(1)子线程耗时操作,主线程更新ui
项目中非常常见的功能,先贴实现代码:
Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber subscriber) { Logger.i("执行耗时操作...."); try { Thread.sleep(5000); subscriber.onNext("耗时操作完成..."); } catch (InterruptedException e) { e.printStackTrace(); } } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() { @Override public void call(String s) { Logger.i(s); } });
再贴输出结果:
实现功能主要通过subscribeOn和observeOn的组合使用,结果中的红框处就是对应分别的工作线程了。
(2)仿AsnycTack实现
大家应该都知道AsyncTask,它可以很容易实现(1),并且它可以更近一步,通过 onPreExecute() 方法在进行耗时任务之前可以让我进行一些准备操作,例如:显示个加载中的“菊花”转,最后 onPostExecute 方法中隐藏“菊花”,就类似下图一样。
以上功能,通过rxjava又是如何实现的呢?继续贴代码。。
@OnClick(R.id.btn2) void onButton2Click(){ unBindSubscription(); subscription= Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber subscriber) { Logger.i("doInBackground()...."); try { Thread.sleep(5000); subscriber.onNext("耗时操作完成..."); } catch (InterruptedException e) { e.printStackTrace(); } } }).subscribeOn(Schedulers.io()).doOnSubscribe(new Action0() { @Override public void call() { progressBar.setVisibility(View.VISIBLE); Logger.i("onPreExecute() ...."); } }).subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() { @Override public void call(String s) { Logger.i("onPostExecute .... ".concat(s)); progressBar.setVisibility(View.GONE); } });}
doOnSubscribe 方法就类似实现了AsyncTask的onPostExecute方法,但是需要注意的是: doOnSubscribe受到后面最近的subscribeOn方法影响运行所在的线程,默认会运行在subscribe()所在的线程。 其他的代码也相对简单,大家可以自己看看。
(3)取消订阅
用rxjava在执行任务的过程当中,如果我们想停止的话,那应该怎么办呢?Subscriber订阅Observable的过程就是处理任务的过程,那么停止任务就是取消订阅操作。如何取消订阅?在仿AsyncTask的例子也提过,答案就是调用Subscription的unsubscribe方法,什么是Subscription?可以简单理解为执行任务的代号,看以下例子就可以很清楚了:
Subscription subscription=Observable.create(new Observable.OnSubscribe(){ @Override public void call(Subscriber subscriber) { for(int i=0;i() { @Override public List call(CharSequence charSequence) { try { if(TextUtils.isEmpty(charSequence)){ return null; } List stringList =new ArrayList(); String key=charSequence.toString(); for (String num: baseDatas){ if(num.contains(key)){ stringList.add(num); } } return stringList; }catch (Exception e){ e.printStackTrace(); } return null; } }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1>() { @Override public void call(List list) { updateData(list); } }, new Action1() { @Override public void call(Throwable throwable) { Logger.e(Log.getStackTraceString(throwable)); } });
代码比较简单就不一一多说了,这里需要注意的地方是: 假如上图为页面一,在页面一打开一个页面二,然后关闭页面二返回页面一的时候,需要重新调用一次代码才能使得功能正常,所以代码一般在onStart方法执行 。
最后再总结一下:本文通过“学习rxjava的好处”引入,和大家分享学习rxjava,首先要了解它的三要素,接着就是操作符合和线程调度学习,最后通过一些项目案例实战和大家分享一些使用经验,但是不管怎样还是得多练习多打码,相信你终有收收获。由于本人水平有限,可能文中存在很多不足,希望大家多多谅解和提出,最后希望本篇文章可以给予那些想学习rxjava的小伙伴一些帮助吧:blush:。
附录:
文章demo
文/Forrest_Zhou
关键字:java, 产品经理
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!