当前位置: 首页 > 面试题库 >

RxJava构建带有Observables的android缓存

越涵衍
2023-03-14
问题内容

我很难理解如何使用RxJava构建缓存。我的想法是我需要从内存缓存中获取数据或从数据库(dynamoDb)加载。但是,该缓存应该在片段和/或线程之间共享。因此,我需要返回当前正在运行但尚未完成的现有可观察对象。这使线程可以赶上而不做不必要的工作。我是RxJava的新手,所以这是我作为草图考虑的内容(为简洁起见,缺少一些代码):

public class DBCache<K, T> {
private final ConcurrentHashMap<K, Set<T>> resultCache = new ConcurrentHashMap<>;
private final ConcurrentHashMap<K, Observable<Set<T>>> observableCache = new ConcurrentHashMap<>;

private Observable<Set<T>> getFromCache(final DynamoDbCacheKey<K, T> query) {
    return Observable.create(new Observable.OnSubscribe<Set<T>>() {
        @Override
        public void call(Subscriber<? super Set<T>> subscriber) {
        Set<T> results = resultCache.get(query.getKey());
        if (results != null && results.size() > 0) {
            subscriber.onNext(results);
        }
        subscriber.onCompleted();
        }
    });
}

public Observable<Set<T>> get(final QueryCacheKey<K, T> query){
    Observable<Set<T>> cachedObservable = observableCache.get(query.getKey());
    if (cachedObservable != null) {
        return cachedObservable;
    }
    Observable<Set<T>> observable = Observable
        .concat(getFromCache(query), getFromNetwork(query))
        .first()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .cache();
    observableCache.putIfAbsent(query.getKey(), observable);
return observable;
}

private Observable<Set<T>> getFromNetwork(final QueryCacheKey<K, T> query) {
    return Observable.create(new Observable.OnSubscribe<Set<T>>() {
    @Override
    public void call(Subscriber<? super Set<T>> subscriber) {
        try {
            Set<T> results = loadFromDb(query); //omitted
            resultCache.putIfAbsent(query.getKey(), results);
            subscriber.onNext(results);
            subscriber.onCompleted();
            observableCache.remove(query.getKey());
        } catch (Exception exception) {
            subscriber.onError(exception);
        }
    }
    });
}

}

是否有更好的方法可以通过RxJava实现(对缓存策略不感兴趣)。有什么想法吗?


问题答案:

下面是一个简单的示例,该示例执行一次缓存并检索一个值:

public class RxCache<K, V> {

    final ConcurrentHashMap<K, AsyncSubject<V>> cache;

    final Func1<K, Observable<V>> valueGenerator;

    public RxCache(Func1<K, Observable<V>> valueGenerator) {
        this.valueGenerator = valueGenerator;
        this.cache = new ConcurrentHashMap<>();
    }

    public Observable<V> get(K key) {
        AsyncSubject<V> o = cache.get(key);
        if (o != null) {
            return o;
        }

        o = AsyncSubject.create();

        AsyncSubject<V> p = cache.putIfAbsent(key, o);
        if (p != null) {
            return p;
        }

        valueGenerator.call(key).subscribe(o);

        return o;
    }

    public void remove(K key) {
        cache.remove(key);
    }
}

如果您有多个值,请替换AsyncSubjectReplaySubject



 类似资料:
  • 注意:如果您已经在使用RxJava或Agera这样的库,那么您可以继续使用它们,而不是LiveData。但是当您使用它们或其他方法时,请确保您正确地处理了生命周期,以便在相关的LifecycleOwner停止时数据流暂停,并且在LifecycleOwner被销毁时数据流被销毁。您还可以添加android.arch.lifecycle:reActiveStreams工件,以便将LiveData与另一

  • 当我尝试使用 离子科尔多瓦构建Android 突然我面临这个错误 未找到已安装的构建工具。安装Android构建工具版本19.1.0或更高版本。0 我确定Android Studio版本(2.1.1 - 22.0.0 - 23.0.0)和最新版本26.0.1的android构建工具 科尔多瓦要求的输出 android的要求检查结果:Java JDK:已安装1.8.0 Android SDK:已安装

  • 有人能解释一下如何在RxJava中通过平面图运算符传递完整信号吗? 如果flatMap操作符被注释,我可以得到从1到10的数字列表,这意味着toList将收到onComplete信号。但当我想在flatMap中进一步处理数据时,它会消耗一个完整的信号,而我无法得到任何结果。如何通过flatMap操作符传递onComplete信号? 我有以下简单的程序:

  • 我是Android Studio的新手。。每当我运行我的项目时,gradle构建大约需要14分钟。。我已经检查了这里提到的提高构建速度的解决方案 我的格拉德尔。属性文件: 但问题仍然是一样的,每一行的颜色都很暗,就像它们是注释行代码一样。当鼠标悬停在顶部时,会出现一条消息,上面写着“未使用的属性。此检查报告所有未从属性文件外部引用的属性” 我怎样才能解决这个问题?谢谢

  • 我正在尝试使用Rxjava解决一个经典的文件验证过程。我有一个带有正常标头的CSV文件和另一个标头列表,我需要验证它们是否属于所选数据类型或值是否为空。 我已经用普通java实现了这一点,但我想让我的验证代码更具反应性。这就是我到目前为止所取得的成就。 在这里,我有3个可观察对象要组合和验证,在验证失败的第一个实例(行)中。 以下是我想使用的示例数据: 标题: 名字|姓|性别|出生|出生|出生|出

  • KnockoutJS基于以下3个重要概念。 它们之间的可观察性和依赖性跟踪 - DOM元素通过“data-bind”连接到ViewModel。 他们通过Observables交换信息。 这会自动处理依赖关系跟踪。 UI和ViewModel之间的声明性绑定 - DOM元素通过“data-bind”概念连接到ViewModel。 模板化以创建可重用的组件 - 模板化提供了一种创建复杂Web应用程序的可