• rxjava各种使用场景


    1. 数据的三级缓存

    final Observable memory = Observable.create(new Observable.OnSubscribe() {
        @Override
        public void call(Subscriber super String> subscriber) {
            if (memoryCache != null) {
                subscriber.onNext(memoryCache);
            } else {
                subscriber.onCompleted();
            }
        }
    });
    Observable disk = Observable.create(new Observable.OnSubscribe() {
        @Override
        public void call(Subscriber super String> subscriber) {
            String cachePref = rxPreferences.getString("cache").get();
            if (!TextUtils.isEmpty(cachePref)) {
                subscriber.onNext(cachePref);
            } else {
                subscriber.onCompleted();
            }
        }
    });
    
    Observable network = Observable.just("network");
    
    //主要就是靠concat operator来实现
    Observable.concat(memory, disk, network)
    .first()
    .subscribeOn(Schedulers.newThread())
    .subscribe(s -> {
        memoryCache = "memory";
        System.out.println("--------------subscribe: " + s);
    });

    取数据,首先检查内存是否有缓存;然后检查文件缓存中是否有;最后才从网络中取;前面任何一个条件满足,就不会执行后面的


    2.界面需要等到多个接口并发取完数据,再更新

    //拼接两个Observable的输出,不保证顺序,按照事件产生的顺序发送给订阅者
    private void testMerge() {
        Observable observable1 = DemoUtils.createObservable1().subscribeOn(Schedulers.newThread());
        Observable observable2 = DemoUtils.createObservable2().subscribeOn(Schedulers.newThread());
    
        Observable.merge(observable1, observable2)
                .subscribeOn(Schedulers.newThread())
                .subscribe(System.out::println);
    }

    3.一个接口的请求依赖另一个API请求返回的数据

        举个例子,我们经常在需要登陆之后,根据拿到的token去获取消息列表。

        这里用RxJava主要解决嵌套回调的问题,有一个专有名词叫 Callback hell

    NetworkService.getToken("username", "password")
        .flatMap(s -> NetworkService.getMessage(s))
        .subscribe(s -> {
            System.out.println("message: " + s);
        });
    4. 界面按钮需要防止连续点击的情况
    RxView.clicks(findViewById(R.id.btn_throttle))
        .throttleFirst(1, TimeUnit.SECONDS)
        .subscribe(aVoid -> {
            System.out.println("click");
        });


    5.响应式的界面
    比如勾选了某个checkbox,自动更新对应的preference
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);
    
    Preference checked = rxPreferences.getBoolean("checked", true);
    
    CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);
    RxCompoundButton.checkedChanges(checkBox)
            .subscribe(checked.asAction());

    6.复杂的数据变换
    Observable.just("1", "2", "2", "3", "4", "5")
        .map(Integer::parseInt)
        .filter(s -> s > 1)
        .distinct()
        .take(3)
        .reduce((integer, integer2) -> integer.intValue() + integer2.intValue())
        .subscribe(System.out::println);//9


    8.Netflix的真实例子

      a..假设我们需要通过一个用户的userId,执行queryA获取他/她所关注的视频列表,列表中的对象是Video类型对象,返回值是Json格式的string。

      b.获取了列表之后我们只需要获取前10个Video对象。

      c.非常不幸的事情是,我们获取的Video对象不是一个完整的Video对象,queryA返回的值还缺少了三个类成员->Rating, Metadata和BookMark.。所以我们得通过Video对象的Id,call三个不同 api来获取缺失的三个值,再讲他们重新填入对应的Video对象。

    那么针对上面的需求我们可以整理一下思路,每一步究竟要做什么:

    Step1:通过userId获取video的数据,这个时候我们需要一个Observable<Video>

    Step2:取前10个对象,这里实现很简单,take(10)足矣,依然是返回Observable<Video>。

    Step3:这一步需要我们进行nested callback了,因为每一个Video对象我们都需要进行三个额外的API call,去获取Rating,MetaData和Bookmark。但是这三个call都是同一时间进行的。所以我们在这一步可以通过flatmap把Step2里面产生的Observable转换成多个(分别是Observable, Observable 和 Observable),并且整合上述三个api call结果并且生成一个新的Observable<Video>返回。

    Step4:在Step3中怎么整合?试试zip() 这个操作符吧!简单的说就是把若干不同的Obervable整合成一个Observable。比如我们最终需要一个A对象,然后A由B和C对象组成,那么假如我们有一个Observable<B>和Observable<C>的话,就可以把这两个Observable zip一下整合成一个Observable<A>。


    zip()

    因为我们需要将三个Api call的结果整合在一起(Rating,MetaData,Bookmark)生成一个Video,所以我们这里选择可以用zip()。

    我们先上代码,分别是Video类,VideoService类


    video类

    Video类的实现比较简单,只是单纯的加入了几个class member。但是注意MetaData, BookMark, Rating这三个member是有getObservable方法的。

    接下里是VideoService类


     

     

     

     

    可以看第一个方法是根据UserId返回原始Video对象的Observable,剩下三个则是根据videoId获取bookmark,rating,metadata的Observable的方法。他们基本上都是差不多的。

    那么在定义好这些方法之后我们要开始调用他们了,调用代码如下:


    开始啦

    我们挑重点一行行解释

    line 26 ->根据userID返回一个Observable<Video>,此时返回的video对象都是不完整的

    line 28 ->只选取10个

    line 30 ->这里我们需要返回一个新的Observable<Video>, 由 line 35- 37的三个Observable zip() 而成

    line 39 - 53 ->三个子Observable互相zipWith(),每次zip都在原来video对象上填充需要的member。

    line 57 -> 我们在安卓的主线程里面handle收到的新Video对象。

  • 相关阅读:
    【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
    【转】wamp 3.0.6(apache 2.4.23) 403 forbidden 解决办法
    身份证第18位(校验码)的计算方法
    【转】Win10开机密码忘了?教你破解Win10开机密码
    【转】具透 | 你可能不知道,iOS 10 有一个中国「特供」的联网权限功能
    钉钉自定义机器人 发送文本 换行 无效果
    屏蔽右键+f12
    【转】理解WebKit和Chromium: JavaScript引擎简介
    第2章 排序 | 第10节 计数排序练习题 && 基数排序
    图像处理-深入探索插值操作
  • 原文地址:https://www.cnblogs.com/huozhong/p/6022767.html
Copyright © 2020-2023  润新知