我使用Android体系结构组件来构建我的应用。这里有分页库,可以加载由Room生成的DataSource
的项目。还有BoundaryCallback
可以从服务器获取新数据并将其存储在数据库中。它工作正常,一切都是反应性的,数据库中的更改进入PagedList。
但是现在我需要这些项目获得一些附加数据,并进行一些计算,然后再将它们输入PagesList
和RecyclerView
中。这些计算并不能很快地在RecyclerView ViewHolder的主线程上执行(实际上,我需要从数据库甚至从服务器获取其他数据)。因此,我认为我需要编写自己的自定义数据源并在那里进行计算,然后将这些经过处理的项目传递给PagedList
。
我创建了ItemKeyedDataSource
(我不确定这是正确的,因为我从数据库中加载了数据,但是此数据源类型是为网络设计的,但我认为这并不重要),并且在Dao中进行查询,以返回List
个项目。获得“页面”后,我对项目进行计算,然后将其传递给回调。它起作用了,PagedList
得到了处理过的项目。
但是不幸的是,这种方法没有反应。我的PagedList没有数据库变化。我试图从Dao返回LiveData<List>
并在observeForever()
中添加DataSource
侦听器,但是由于您无法在后台线程上运行它而失败了。
我看着Room生成了DataSource.Factory
和LimitOffsetDataSource
,但它对我来说并不好,因为您需要传递表名来观察更改和其他不清楚的事情。
我想我需要使用invalidate(),但是我不需要,因为我不知道应该在哪里。
主要有3个问题:
DataSource
中处理项目之前,RecyclerView
还是有更好的地方?PositionalDataSource
而不是ItemKeyedDataSource
吗?DataSource
中?答案 0 :(得分:0)
似乎我在DataSource.Factory
中发现了一个错误。我没有返回create()
方法中的DataSource对象,而是返回了传递给该工厂的对象(我在Medium上的一篇热门文章中看到了它)。因此,我无法使我的DataSource
无效。但是现在我用这种方法创建了DataSource
,并且无效了。
唯一的问题是了解何时何地使之无效。目前,我已经找到了一些解决方法:在Dao中进行查询,返回上一项的LiveData
,然后在“活动”中对其进行观察以了解数据已被修改并调用invalidate()
。但是我不确定这是否是一个好的解决方案。也许你知道更好的一个。
答案 1 :(得分:0)
您可以在数据源中添加invalidationTracker:
dbRoom.getInvalidationTracker().addObserver(
object : InvalidationTracker.Observer("your_table") {
override fun onInvalidated(@NonNull tables: Set<String>) {
invalidate()
}
})