Rxjava使用场景

前言

开始接触并且尝试的去应用Rxjava是从抛物线的这篇文章给 Android 开发者的 RxJava 详解开始的,陆陆续续的我也看了两三遍,也越来越发的发现Rxjava真的非常非常的强大。
到目前为止,越来越多的的开发者开发者开始使用Rxjava,github上的Rxjava项目也不知道有多少,而且MVP+Rxjava+Retrofit好像是很多开源项目的标准配置(😄😄),所有,我也不能落后,这不,我也在公司的项目中慢慢的去使用Rxjava,而且现在应用的场景也越来越多。
多余的话也不说了,就说说我从环境配置到使用的一步一过程,一边是我自己的一个笔记,一边是给那些初学者一点思路。

Rxjava介绍

开始Rxjava之前,首先我们要弄清楚Rxjava到底是一个什么东东。
Rxjava中github主页上的介绍是:
RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.
翻译过来就是:一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。
结合我使用的过程,使用这两个词可以概括“异步”,“逻辑简洁”

引入

compile 'io.reactivex:rxjava:1.1.6'
compile 'io.reactivex:rxandroid:1.2.1'

查看引入最新版本可以去github主页
如果中项目中使用Rxjava+Retrofit结合,同时要引入

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

使用场景

由于Rxjava使用基础中很多文章中都有写,再写也都是一样的,我这里就用一些具体的场景来介绍我使用的过程
开始之前推荐两片文章,也是我看了多次觉得比较好的
给 Android 开发者的 RxJava 详解
Rxjava从入门到出轨

废话讲的比较多,开始具体场景

场景一:延迟处理

几乎每一个项目都会有引导也,之前我们通常使用的方式是Handler延迟处理,那切换到Rxjava呢?如何实现?
这里会用到Rxjava的timer操作符,timer的具体介绍再这里也不过的的说了,可以到ReactiveX/RxJava文档中文版或者github查看
回归到延迟操作,具体实现如下

Observable
.timer(2, TimeUnit.SECONDS)
.subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                   //TODO    
            }
});

上看我们用到的是Rxjava不完整回调,而Rxjava定义来三中不完整回到

  • observable.subscribe(onNextAction);
  • observable.subscribe(onNextAction, onErrorAction);
  • observable.subscribe(onNextAction, onErrorAction, onCompleteAction);

特别要注意的是,如果你无法把握Rxjava事件的订阅消费流程,最好是使用完整的回调

Subscriber<String> subscriber = new Subscriber<String>() {
          @Override
          public void onNext(String s) {
          }
          @Override
          public void onCompleted() {
          }
          @Override 
          public void onError(Throwable e) {
          }
};

之所以在这里强调这个,是因为我在使用的过程,有事场景需要处理结果,而我直接使用的observable.subscribe(onNextAction)的不完整调用,而忽略了可能出现的异常情况,或者其他不确定的情况而导致报错闪退,具体错误

java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
场景二:短信定时器

现在的应用基本上都是手机注册+第三方登录,所有手机短信验证是必不可少的,而发送短信的过程我们要使用定时器来处理短信接收过程以及发送失败的情况,Rxjava之前我们使用的是Handler+Timer+TimerTask,这情方式的麻烦程度就不用我多说了,下面我们来看看Rxjava的是怎么实现的。。。
直接撸代码:

 subscription = Observable.interval(0, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Func1<Long, Integer>() {
                    @Override
                    public Integer call(Long increaseTime) {
                        return countTime - increaseTime.intValue();
                    }
                })
                .take(30)
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        LogUtils.e("================doOnSubscribe");
                        timeText.setVisibility(View.VISIBLE);
                        failLayout.setVisibility(View.GONE);
                    }
                })
                .doOnUnsubscribe(new Action0() {
                    @Override
                    public void call() {
                        LogUtils.e("================doOnUnsubscribe");
                        stopSubScribe();
                    }
                })
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        timeText.setVisibility(View.GONE);
                        failLayout.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(Integer integer) {
                        LogUtils.e("================"+integer);
                       timeText.setText(Html.fromHtml(String.format(getResources().getString(R.string.verify_code_time), "<font color=\"#3d9bf5\">" + integer + "秒</font>")));
                    }
                });

private void stopSubScribe() {  
          if (subscription != null) {    
                subscription.unsubscribe();   
           }
}

下面我们来分析一下上面的代码,首先是是interval(间隔一定时间发送一个数字,从0开始.本身运行在Schedulers.computation() 线程内)操作符,它是定时器使用的主要操作符,接下来observeOn说明了定时操作发生在主线程,然后就是map操作符执行了时间减1的操作,接下来是take(只保留前面的若干项数据)操作符,我们设计定时器不可能让它一直走下去,肯定是到位置执行我们制定的操作的,所以这里的take就非常重要了,从它给的意思我们能理解在这里设置take为30表示定时器执行到30秒回自动结束,所以,interval和take结合真的很完美,接下来我们看另外两个操作符doOnSubscribe,doOnUnsubscribe,它们会在Subscriber进行订阅和反订阅的时候触发回调,既是开始时我们调用doOnSubscribe,结束时调用doOnUnsubscribe。最后我们在完成的时候调用了自定义的stopSubScribe方法,用在这里的目的是为了让subscription 使用完成了就解绑订阅,不占用系统资源,同时也避免内存溢出,所有,使用完subscription 后要尽可能的把他解绑释放。

场景三:多接口调用

有些功能无法一个接口能实现了,比如我们上传一张图片到七牛,首先我们获取七牛token,上后根据token上传图片到七牛云服务器得到图片url,最后把图片url提交到我们自己的数据库中,这个场景中我们相当于执行了三次操作,那我们怎样使用rxjava去实现呢?
直接上代码

  Subscription subscription = qiniuRep.getQiniuToken()
                    .flatMap(new Func1<String, Observable<String>>() {
                        @Override
                        public Observable<String> call(final String token) {
                            return qiniuRep.uploadImageToQiniu(token, path);
                        }
                    })
                    .flatMap(new Func1<String, Observable<UserEntity>>() {
                        @Override
                        public Observable<UserEntity> call(String avater) {
                            return userRep.updateUserInfo(UserManager.getToken(), UserManager.getUid(), nick_name, gender, birth, area, describe, avater);
                        }
                    })
                    .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(Integer integer) {
                    }
                });

现在是不是看起来非常清晰,从上到下,一步步执行。代码也非常清晰,就不做过多的描述了。

未完待续。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,444评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,867评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,157评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,312评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,673评论 3 289
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,802评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,470评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,696评论 2 250
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,187评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,538评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,188评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,127评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,889评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,741评论 2 274

推荐阅读更多精彩内容