当前位置: 首页 > 知识库问答 >
问题:

RxJava可见。缓存失效

洪伟彦
2023-03-14

我正在尝试在Android环境中学习rxjava。比方说,我有一个可观察的对象,它发出网络调用的结果。如果我理解正确的话,处理配置更改的一种常见方法是:

>

  • 将可观察对象存储在保留的片段/单例/应用程序对象中

    将缓存操作符应用于可观察对象

    在正确的生命周期处理程序中订阅/取消订阅

    这样做,我们就不会失去可观察到的结果,一旦新配置发生,将重新观察到该结果。

    现在,我的问题是:

    有没有办法强制可观察对象发出新值(并使缓存的值无效)?每当我想从网络上获取新数据时,我是否需要创建一个新的可观察对象(这在android世界听起来并不是一个糟糕的做法,因为这会让gc做额外的工作)?

    谢谢,

    费德里科

  • 共有1个答案

    孔君浩
    2023-03-14

    制作一个自定义的OnSubscribe实现,它可以做你想要的:

    public static class OnSubscribeRefreshingCache<T> implements OnSubscribe<T> {
    
        private final AtomicBoolean refresh = new AtomicBoolean(true);
        private final Observable<T> source;
        private volatile Observable<T> current;
    
        public OnSubscribeRefreshingCache(Observable<T> source) {
            this.source = source;
            this.current = source;
        }
    
        public void reset() {
            refresh.set(true);
        }
    
        @Override
        public void call(Subscriber<? super T> subscriber) {
            if (refresh.compareAndSet(true, false)) {
                current = source.cache();
            }
            current.unsafeSubscribe(subscriber);
        }
    
    }
    

    这段代码演示了使用情况,并显示缓存实际上正在重置:

    Observable<Integer> o = Observable.just(1)
            .doOnCompleted(() -> System.out.println("completed"));
    OnSubscribeRefreshingCache<Integer> cacher = 
        new OnSubscribeRefreshingCache<Integer>(o);
    Observable<Integer> o2 = Observable.create(cacher);
    o2.subscribe(System.out::println);
    o2.subscribe(System.out::println);
    cacher.reset();
    o2.subscribe(System.out::println);
    

    输出:

    completed
    1
    1
    completed
    1
    

    顺便说一下,您可能会注意到。缓存在完成之前不会发出。这是一个应该由rxjava 1.0.14修复的bug。

    就GC压力问题而言,每个操作员在应用于可观察对象时,通常通过提升或创建来创建新的可观察对象。与创建新可观察对象相关的基本成员国是对Subscribe函数的引用<代码>缓存与大多数缓存的不同之处在于,它跨订阅保存状态,如果它保存大量状态并经常被丢弃,则可能会产生GC压力。即使您使用相同的可变数据结构在重置过程中保持状态,GC在清除时仍然必须处理数据结构的内容,因此您可能不会获得太多收益。

    RxJava缓存操作符是为多个并发订阅而构建的。您可能会想象,重置功能的实现可能会出现问题。如果您想进一步探索,请务必在RxJava github上提出一个问题。

     类似资料:
    • 看下这个段伪代码: local value = get_from_cache(key) if not value then value = query_db(sql) set_to_cache(value, timeout = 100) end return value 看上去没有问题,在单元测试情况下,也不会有异常。 但是,进行压力测试的时候,你会发现,每隔 100 秒,数据库的

    • 我在Spring3.1中使用@Cacheable。我对Cacheable中的值和键映射参数有点混淆。以下是我正在做的: 这里发生的情况是,第二个方法依赖于第一个方法的选定值,但问题是假设当我传递zoneMastNo=1和areaMastNo=1时,第二个方法返回第一个方法结果。事实上,我有很多服务,因此,我希望使用公共值来缓存特定的用例。现在我的问题是: 我如何解决这个问题 对每个服务都使用cac

    • 我有一个项目列表,需要提取一些值并为每个项目调用api。为了做到这一点,我用了这样的东西_ 好吧,问题是,我不知道为什么所有的调用都是并行的。难道它不应该等待第一个响应,映射结果,然后从可观察到的对象开始下一个项目吗。from()并在最后返回responseMessages的最终列表?正在发生的是,一切都同时发生。为了证实这一点,如果我在toList方法之前加上一个延迟(1,TimeUnit.Se

    • 我想同步发射两个可观测对象(它们是异步的),一个接一个地返回第一个发射的可观测对象。如果第一个失败,则不应发出第二个。 假设我们有一个Observable可以让用户登录,另一个Observable可以在登录后自动选择用户的帐户。 这就是我所尝试的: 不幸的是,这不适用于我的用例。它将发出/调用两个平行的观测值,从“ob1”开始。 是否有人遇到过类似的用例?或者有没有一个想法,如何让可观测对象以同步

    • 主要内容:RxJava Buffering缓冲 介绍,RxJava Buffering缓冲 示例RxJava Buffering缓冲 介绍 缓冲运算符允许将 Observable 发出的项目收集到列表或包中,并发出这些包而不是项目。在下面的示例中,我们创建了一个 Observable 来发出 9 个项目,并且使用缓冲,3 个项目将一起发出。 RxJava Buffering缓冲 示例 输出结果为:

    • 我正在使用注释来缓存我的方法的结果。出于性能原因,我想缓存从方法返回的和非null值。 但是这里的问题是Spring缓存非空值,但由于某种原因没有缓存空值。 这是我的密码: 我什么都试过了。就连我 但这也没什么帮助。有关于这个的指示吗?