RxJava小贴士-创建Observable

在使用RxJava的第一步就是创建一个你所需要的Observable,根据不同的需求创建不同的Observable。

首先你得了解Observable的分类

Observable分类

  • Cold Observable

    当没有订阅的时候,该Observable不处理任何事件,当有订阅者发起订阅后,才开始响应,从第一个数据开始发射。

  • Hot Observable

    不管有没有订阅者,该Observable一直在发射数据。

关于‘冷’、‘热’我是这样理解的:‘冷’的Observable是默认定义了数据或者获取数据的方式,每次订阅后将所有的数据,按照一定的规则发射给你;‘热’则是动态的数据,而这个被观察者一直处于发射状态,当你订阅后,其实就是从现在开始接收到数据而已,这里的数据都是动态的、实时变化的,而不是定义Observable就把数据默认好了。

如何选择合适的Observable

  • 已经获取到的数据进行处理 -Cold

    比较典型的例子,筛选一个数组中所有的偶数

    Integer[] array = new Integer[]{1,2,3,4,5,6,7,8};
            Observable.fromArray(array)
                    .filter(item -> item%2 == 0)
                    .subscribe(item -> System.out.println("item#"+item));
    

    如果你单独创建一个Observable.fromArray(array)这个被观察者是没有处理任何事件

  • 触发一个固定事件获取数据-Cold

    这种一般用于异步获取数据,比如网络请求:

        //模拟一个耗时3秒的请求
        String getData(){
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "test";
        }
    
        Observable.create((ObservableOnSubscribe<String>) e -> {
                try {
                    System.out.println("start#"+System.currentTimeMillis());
                    String data = getData();
                    e.onNext(data);
                          //一般这种获取数据方式的被观察者,获取到一个数据后就调用onComplete
                    e.onComplete();
                }catch (Exception e1){
                    e.onError(e1);
                }
            }).observeOn(Schedulers.newThread())
              .subscribe(data->{
                System.out.println("data#"+data);
                System.out.println("end#"+System.currentTimeMillis());
              });
    

    结果

    start#1493776191045
    data#test
    end#1493776194051
    

    这种方式创建的Observable也是的,可以在Demo去掉subscribe订阅,就会发现实际这个Observable什么事情都没做。

  • 创建一个当前状态的Observable-Hot

    这种Observable实际运用中非常有用、方便、简洁。比如对Activity的生命周期,可以做一个Observable,当生命周期改变时,对其发射数据。对TextView的text变化创建一个Observable,每当text变化的时候发射给订阅者,等等。

    这里已TextView text变化为例:

    这里使用BehaviorSubject而不使用PublishSubject是因为,在实际使用中我们需要从订阅开始那一刻就知道目前TextView的text是什么,使用BehaviorSubject会在订阅那一刻将最后一次发射的数据发射给订阅者,而PublishSubject则是订阅开始后,直到下次有text变化,那订阅者才能接收到第一个数据。

    创建一个工具类TextViews.java

    public static Observable<CharSequence> textChange(final TextView textView){
              //创建Observable,并对其设置默认值
            BehaviorSubject<CharSequence> observable = BehaviorSubject.createDefault(textView.getText());
            TextWatcher textWatcher = new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {}
              
                @Override
                public void afterTextChanged(Editable s) {
                    observable.onNext(s);
                    Log.d("RxJava","onChange");
                }
            };
            textView.addTextChangedListener(textWatcher);
              //doOnDispose 当取消订阅时候响应,同时取消监听
             return observable.doOnDispose(()->{
                textView.removeTextChangedListener(textWatcher);
                observable.onComplete();
            });
        }
    

    使用

    EditText editText = (EditText) findViewById(R.id.edit);
    
    final Disposable disposable = TextViews.textChange(editText)
      .subscribe(text-> Log.d("RxJava","text#"+text));
    //点击按钮取消监听
    findViewById(R.id.cancel).setOnClickListener(v ->{
      if(!disposable.isDisposed()){
        disposable.dispose();
      }
    });
    

    在后续实际开发中基本只需要关心怎么使用textChange所返回的数据,而其变为Observable之后操作很多事件就变得很方便

    比如将其变为监听text长度

    TextViews.textChange(editText)
      .map(CharSequence::length)
      .subscribe(len-> Log.d("RxJava","text#"+len));
    

    对于一个button,当Edittext的text长度大于4才能点击

    TextViews.textChange(editText)
      .map(CharSequence::length)
      .map(len->len>4)
      .subscribe(button::setEnabled);
    

总结
关于创建Observable的方式还有很多,这里简单说了我自己最常用的部分。希望大家能给大家带来一定的帮助。如果有错误的地方指出来,大家都共同学习下。

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

推荐阅读更多精彩内容