我正在将我的应用程序转换为会议室数据库,并尝试遵循基于“带有视图的会议室”的google体系结构最佳做法。
我很难从干净的架构上了解存储库。
Words数据库示例仅包含一个表和一个使用该表的视图,这使其成为一个简单的HelloWorld示例。但是让我们开始吧。
有一个显示单词列表的视图。因此,所有单词都需要从数据库中读取并显示。因此,我们有一个MainActivity和一个要连接的数据库。
如果在数据更改时更新视图,那就很好了,所以使用LiveData。
这意味着存储库正在为整个表提供LiveData:
// LiveData gives us updated words when they change.
val allWords: LiveData<List<Word>>
这对单个视图来说都很好。
现在我对扩展这个概念有疑问。
让我们假设,单词表具有两列“ word”和“ last_updated”作为时间字符串。
为了便于比较,时间字符串需要转换为毫秒,所以我有一个函数。
问题:将有趣的queryMaxServerDateMS()放在哪里以获取最大值(最后更新)?
/**
* @return Highest server date in table in milliseconds or 1 on empty/error.
*/
fun queryMaxServerDateMS(): Long {
val maxDateTime = wordDao.queryMaxServerDate()
var timeMS: Long = 0
if (maxDateTime != null) {
timeMS = parseDateToMillisOrZero_UTC(maxDateTime)
}
return if (timeMS <= 0) 1 else timeMS
}
对我来说,将其放入WordRepository是很自然的。
第二要求:后台作业以更新数据库中的单词列表。
假设我现在希望定期安排一个后台作业,以检查服务器是否创建了新条目并将其下载到数据库。该应用程序可能无法打开。
此问题仅是上述queryMaxServerDateMS的问题。
该工作基本上会首先检查,是否通过询问服务器是否存在比最大已知条目新的条目来创建新条目。
因此,我需要获取一个新的类WordRepository,进行查询,获取最大的last_update并询问服务器。
但是:我不需要在后台作业中使用LiveData,并且当val repositoy = WordRepository时,将读取整个表,这是不必要的,并且会浪费时间,内存和电池。
[我也可以想到许多不同的片段,它们需要单词表的一些数据,但不需要完整的数据,请考虑列出一个产品的产品详细信息屏幕。
因此我可以将其移至另一个存储库或DbHelper,但您想调用它。
但是最后,我想知道是否要使用LiveData,它要求将View,ViewModel和Repository紧密耦合在一起:
问题:我是否需要为每个活动/片段存储一个库,而不是为每个表都具有一个存储库呢?
Repository
。在Clean架构中,有一个UseCase / Interactor概念,它可以包含业务逻辑,而在Android中,它可以充当ViewModel
和Repository
之间的附加层,您可以为函数queryMaxServerDateMS()
创建一些UseCase类,将其放在此处,然后从您需要的任何ViewModel
中调用它。
此外,您也可以通过调用LiveData
来同步获取getValue()
值。