VictorAlbertos / RxCache

Reactive caching library for Android and Java
Apache License 2.0
2.38k stars 192 forks source link

json转换AjaxResult<List<T>>这种类型会报下面的错 #125

Open catchpig opened 6 years ago

catchpig commented 6 years ago

io.reactivex.exceptions.UndeliverableException:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to zhuazhu.readhub.mvp.hot.model.HotNews

JessYanCoding commented 6 years ago

https://github.com/VictorAlbertos/RxCache/issues/73

XiFanYin commented 6 years ago

@JessYanCoding 在一次请求中先读取缓存展示UI,等请求到数据之后再次拿最新数据更新UI的需求目前这个库能满足嘛?

JessYanCoding commented 6 years ago

你请求两次不就可以了,缓存时间调长一点,第一次请求缓存,第二次不使用缓存直接请求网络

XiFanYin commented 6 years ago

@JessYanCoding 我理解你的意思如下: 假如设置缓存时间设置:永久有效 。

 //正常网络请求
    Observable<Patient> patientInfo = RetrofitUtil
            .getInstance()
            .create(API.class)
            .getPatientInfo(1, 2);
    //读取缓存数据
    CacheProviderUtils
            .getInstance()
            .using(Provider.class)
            .getPatientInfo(patientInfo, new DynamicKey("eee"), new EvictDynamicKey(false))
            .compose(RxSchedulers.io_main())
            .compose(bindUntilEvent(ActivityEvent.DESTROY))
            .subscribe(new BaseObserver<Patient>() {
                @Override
                public void onNext(Patient patient) {
                    //只读取缓存数据,这里没有去更新缓存
                }
            });
    //只请求网络
    patientInfo
            .compose(RxSchedulers.io_main())
            .compose(bindUntilEvent(ActivityEvent.DESTROY))
            .subscribe(new BaseObserver<Patient>() {
                @Override
                public void onNext(Patient patient) {
                    //只请求网络数据,也没有去更新缓存
                }
            });

这个时候会发现缓存没有更新。

然后就需要修改请求网络代码添加缓存如下: CacheProviderUtils .getInstance() .using(Provider.class) .getPatientInfo(patientInfo, new DynamicKey("eee"), new EvictDynamicKey(true)) .compose(RxSchedulers.io_main()) .compose(bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new BaseObserver() { @Override public void onNext(Patient patient) { //这里就变成了每次都去请求网络,然后去更新缓存 } }); 也完成我上边所说的需求,先获取缓存展示缓存,然后再获取网络数据,更新缓存,更新UI.

有没有一种这样封装的可能:一次请求,响应流回调两次,一次是缓存,一次是网络 伪代码: CacheProviderUtils .getInstance() .using(Provider.class) .getPatientInfo(RetrofitUtil .getInstance() .create(API.class) .getPatientInfo(1, 2), new DynamicKey("eee"), new EvictDynamicKey(false)) .compose(RxSchedulers.io_main()) .compose(bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new BaseObserver() { @Override public void onNext(Patient patient) { // 这里回调两次, 第一次是读取缓存的, 第二次是读取网络的

                }
            });

当然对于不同的使用者会有不同的需求,去设置几种注解来调整缓存模式的读取。通过注解接口去完成。

这是我的一个想法,会让缓存使用更加舒服~

我不知道这个想法会不会不切实际,因为目前来说,我还没有响应式变成思想,不知道一个上流能不能让下流回调两次。

谢谢~

JessYanCoding commented 6 years ago

想法不错,回掉两次应该是没问题的,但这个恐怖只有改源码了,你给我说没用...,你该给作者沟通,或者自己修改源码

XiFanYin commented 6 years ago

@JessYanCoding 我这个英语水平怕把作者气死也表达不清楚,所以你沟通一下子。如果你觉得这个想法可以,可以跟作者沟通一下。毕竟你们大神之间的交流比较顺畅!

JessYanCoding commented 6 years ago

我英语也很一般,而且我最近事情太多了,才开源了一个库 AndroidAutoSize,star 拿的多,但找我提 issues 的人也一抹多,而且你也晓得我还有 MVPArms,ArmsComponent 以及其他一钩子的库,要维护,其他库的事情我是真的没心思管,这个库我也只是好心帮他写了中文文档,仅此而已,建议你自己改源码,这种需求和业务有关,看作者的活跃状况,百分 90 都不会帮你实现这个需求的

XiFanYin commented 6 years ago

好的,理解你,谢了!你的mvpArms运用dagger2封装的真的很巧妙,注入的也非常巧妙。巧妙的已经没法用言语描述了,感谢刷新了我的对Dagger2的认识

JessYanCoding commented 6 years ago

@XiFanYin 感谢支持

xilost commented 5 years ago

@JessYanCoding @JessYanCoding 有个问题就是,如果new EvictDynamicKey(true)且useExpiredDataIfLoaderNotAvailable=true,断网进入,第一次能够返回缓存,同时这个时候缓存被清除,第二次断网进入就没有数据了。