我有一个ListView / RecyclerView。现在,我想为每个项目添加更多信息,并且可以根据项目值在数据库中找到信息。你会怎么做到的???
对于最佳实践,我应该在后台线程中查询数据库吗?如果用户快速滚动,我应该取消查询吗?
答案 0 :(得分:2)
没有“最佳实践”AFAIK,但以下是您的选项的简短摘要:
用户滚动时在UI线程上进行查询
通常,在UI线程上执行查询通常是一种非常糟糕的做法。在ListView中执行此操作是一种罪过。
也就是说,有些ORM库在UI线程(例如GreenDAO)上执行嵌套对象的延迟加载。人们在具有ListView的应用程序中使用这些库,它甚至可以用于其中一些。
我强烈反对这种方法。
提前查询所有项目
正如@CommonsWare所提到的,对于中小型集合,您只需将整个数据集加载到后台线程的内存中,然后将其绑定到ListView即可。在加载数据时,您需要显示某种进度指示。
“小”和“中”的定义非常模糊,但我要说如果你确定数据集不会超过几MB,那么这种方法可以很好地工作。
此方法的缺点是用户需要等待加载整个数据集并绑定到ListView。根据数据集的大小和数据库方案的复杂性,这可能需要一段时间。
最初查询预定义数量的项目,然后在用户滚动时执行其他查询
这是最复杂的方案,但在某些情况下(例如“无限列表”)是不可避免的。
我们的想法是将一些预定义数量的项目添加到ListView中,然后跟踪用户的交互以提供其他项目。
例如,您最初可以获取100个项目,然后在用户滚动到列表末尾时再获取100个项目。
此方案的优化是在用户到达列表末尾之前获取其他项目(让我们说当他滚动浏览50个项目时)。这允许创建真正的“无限列表”行为。
请注意,如果您的收藏非常大,您不仅需要注意在用户滚动时添加新项目,还要注意删除“之前”项目以避免内存崩溃。
查询已显示的项目的其他信息
有时您希望在项目显示后执行一些其他查询。
在这种情况下,只需在后台执行查询并将数据绑定到项目。
此任务的一个警告是,如果项目的视图被回收(默认情况下在RecyclerView中就是这种情况),那么当您完成后台提取时,目标视图可能会显示完全不同的项目。将返回的数据绑定到此视图将是一个错误。
处理此问题的一种方法是取消提取。但是,这在实践中很麻烦且容易出错。
更简单的方法是在启动查询时设置transientState
标志,并在查询完成时清除它。