gpt4 book ai didi

Android:在 DAO 中使用 Room 数据库和 LiveData 的整洁架构

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:55:53 25 4
gpt4 key购买 nike

我正在尝试将整洁的架构方法应用到我的项目 ( Link: guide I'm currently referencing )。

我正在使用 Room 数据库进行本地存储,我希望它成为应用程序中的单一数据源 - 这意味着从网络调用收集的所有数据首先保存在数据库中,然后才传递给演示者。 Room 提供从其 DAO 返回的 LiveData,这正是我需要的。

不过,我也想使用存储库作为访问数据的单一方式。这是领域层(最抽象的一个)中存储库接口(interface)的示例:

interface Repository<T>{
fun findByUsername(username: String) : List<T>
fun add(entity: T): Long
fun remove(entity: T)
fun update(entity: T) : Int
}

我在这里遇到了问题 - 我需要在我的 ViewModel 中从 Room 的 DAO 获取 LiveData,并且我想使用 Repository 实现来获取它。但为了实现这一目标,我需要:

  1. 更改存储库方法 findByUsername 以返回 LiveData>
  2. 或者直接从 ViewModel 调用 Room 的 DAO,完全跳过存储库实现

这两个选项都有足够的缺点:

  1. 如果我导入 android.arch.lifecycle.LiveData进入我的 Repository 接口(interface)而不是破坏域层中的抽象,因为它现在依赖于 android 架构库。
  2. 如果我在 ViewModel 中直接调用 Room 的 DAO 作为 val entities: LiveData<List<Entity>> = database.entityDao.findByUsername(username)然后我打破了所有数据访问必须使用 Reposiotry 的规则,我将需要创建一些样板代码以与远程存储等同步。

如何使用 LiveData、Room 的 DAO 和 Clean 架构模式实现单一数据源方法?

最佳答案

从技术上讲,您遇到了麻烦,因为您不想同步获取数据。

 fun findByUsername(username: String) : List<T>  

您想要一个返回给您新的 List<T> 的订阅每次都有变化。

 fun findByUsernameWithChanges(username: String) : Subscription<List<T>>

所以现在你可能想要做的是制作你自己的订阅包装器来处理 LiveDataFlowable .当然,LiveData比较棘手,因为您还必须给它一个 LifecycleOwner。

public interface Subscription<T> {
public interface Observer<T> {
void onChange(T t);
}

void observe(Observer<T> observer);

void clear();
}

然后是类似的东西

public class LiveDataSubscription<T> implements Subscription<T> {
private LiveData<T> liveData;
private LifecycleOwner lifecycleOwner;

private List<Observer<T>> foreverObservers = new ArrayList<>();

public LiveDataSubscription(LiveData<T> liveData) {
this.liveData = liveData;
}

@Override
public void observe(final Observer<T> observer) {
if(lifecycleOwner != null) {
liveData.observe(lifecycleOwner, new android.arch.lifecycle.Observer<T>() {
@Override
public void onChange(@Nullable T t) {
observer.onChange(t);
}
});
} else {
Observer<T> foreverObserver = new android.arch.lifecycle.Observer<T>() {
@Override
public void onChange(@Nullable T t) {
observer.onChange(t);
}
};
foreverObservers.add(foreverObserver);
liveData.observeForever(foreverObserver);
}
}

@Override
public void clear() {
if(lifecycleOwner != null) {
liveData.removeObservers(lifecycleOwner);
} else {
for(Observer<T> observer: foreverObservers) {
liveData.removeObserver(observer);
}
}
}

public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
this.lifecycleOwner = lifecycleOwner;
}
}

现在您可以使用您的存储库

val subscription = repository.findByUsernameWithChanges("blah")
if(subscription is LiveDataSubscription) {
subscription.lifecycleOwner = this
}
subscription.observe { data ->
// ...
}

关于Android:在 DAO 中使用 Room 数据库和 LiveData 的整洁架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50752390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com