RxJava2中重要操作符在实际项目应用(六)

1、zip

功能说明:合并从不同的数据源获取的数据(有两个接口),然后展示数据.

我在项目中的应用是:将第三方广告接口返回的数据 夹杂 到自加平台返回的广告数据 并且展示出来。

详情使用请参见:zip在项目中的使用


2、flatMap

作用:网络嵌套请求。

我在项目中的应用:服务器出于安全考虑,一些接口需要传入token才能返回正确的数据。而token需要从另一个接口获得。这时使用flatMap发起嵌套的网络请求就非常合适,这样的代码会非常的清晰、整洁。

示例:

1)接口




2)获取到的请求实体:TokenEntity和MyInfoEntity(我就不给大家列了)


3)使用 flatMap 发起嵌套的网络请求:


运行结果:


这样就搞定了是不是很简单。不知道大家听懂登录没有。我再举个例子:当用户注册成功以后,再去做登录,这个也是可以用flatMap来实现的。


3、retrywhen

我在项目中的具体使用:我们都知道Token并非是一次性的,而是可以多次使用的。(而我的项目中Token发生改变的情形是账号在另一台手机上登录,这时token就发生了改变,而当前的这架手机再发起数据请求时是请求不到数据的,因为这时的token发生改变)。由于token失效而获取数据失败,这种情景是非常的常见,这样的token处理起来也是比较麻烦的。因为多处的接口都需要token,我们需要把它保存起来,并且当发现token失效的时候要能够自动重新获取新的token来访问因为token失效的接口。如果这样使用原来的Callback来实现是非常的困难。而如果使用 了太容易When来实现的话那就非常非常的简单了。

在项目中的使用示例:

    //假设从共享参数获取到的Token
    String token="1234";
    //可重试的最大次数
    int maxCount=3;
    //当前重试的次数
    int retryCount=0;
    private void doRxJava6() {
    
        RetrofitFactory.getRetrofit().create(NetApi.class).requestMyInfo(token)
                .subscribeOn(Schedulers.io())
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {
                        //捕获异常
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {
                                //判断是否是空指针异常,如果是空指针异常,那表示Token已经过期(我的后台如果Token发生错误返回的就是空指针异常)
                                if (throwable instanceof NullPointerException){
                                    //表示Token已经过期,需要获取新的Token
                                    //判断重试的次数
                                    if (retryCount<maxCount){
                                        //记录重试的次数
                                        retryCount++;
                                        Log.e("RxJava","重试的次数:"+retryCount);
                                        RetrofitFactory.getRetrofit().create(NetApi.class).requestToken("17310851776","123456")
                                                .subscribeOn(Schedulers.io())
                                                .doOnNext(new Consumer<TokenEntity>() {
                                                    @Override
                                                    public void accept(@NonNull TokenEntity tokenEntity) throws Exception {
                                                        //保存一下新的Token
                                                        token=tokenEntity.getData().getToken();
                                                    }
                                                });
                                        //让原始的Observable重新发送数据
                                        return Observable.just(1);

                                    }else{
                                        //表示超过了重试次数,让原始的Observable不在发送数据
                                        return Observable.error(throwable);
                                    }
                                }
                                return Observable.error(throwable);
                            }
                        });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Object o) {
                        System.out.println("接收到数据:"+o);

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        System.out.println("对Error作出响应:"+e);

                    }

                    @Override
                    public void onComplete() {

                    }
                });
        
    }

这个理解起来有点复杂,建议大家动手写一写就明白了其中的道理了。


4、从磁盘 或者 内存 获取缓存数据

流程图:


数据缓存在App中我很会很经常的和缓存打交道。

1、数据的时效性:

常见的此类应用:新闻、社区。这类的app无论是否存在缓存,都是请求网络。这类的app的特点在于先显示缓存的数据,然后再去请求网络,显示最新的数据。

2、数据定期更新或者更新不频繁:

此类常见的app:小说,应用市场等。这类应用特点是:给缓存设置一个过期的事件,只要时间未过期就优先使用缓存的数据。当缓存过期以后再访问网络获取新的数据。

3、不需要缓存:打车、金融服务等。此类App的需要的是实时性,所有缓存就没有意义了。


而缓存中我们离不开的就是图片的缓存。因为图片缓存比较特殊,它占用的内存较大,即使是本地的图片,也会有较大的延迟。所以用该用到的是三级缓存策略:内存+本地+网络。但是这其中也会有很多的问题存在:

1、内存不足(OOM)

如果把图片全部缓存到内存,我相信过不了多久就会出现OOM。所以,只能部分的缓存到内存。这时候,内存缓存的问题就变成了选择缓存图片的问题。常见的选择策略是LRU(近期最少使用的算法)。

2、内存存储过多:

和内存一样,即使是本地存储,也不可能无限量的存储。我们需要做的就是当本地缓存满的时候,优先清除较老的数据。

是不是图片缓存觉得非常的麻烦,不过幸好图片加载的开源框架已经帮我们做好了,比如Glide。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值