我只在Android 9上观察到了这种情况,可能只有在三星设备上才观察到。稍后,我将对多个序列化字符串的多个JSON响应存储到数据库中,以进行类型转换,再次使用Moshi将其转换为模型。
导致此错误的查询是:
@Query(“SELECT * FROM tasks”)
public abstract Flowable<List<TaskEntity>> getAll();
最后一个实例在表中共有大约392,000个字符。实际上,这些内容在表格中分为大约5500个字符大小的条目。
谢谢。
答案 0 :(得分:1)
我选择*的事实是否意味着光标将整个表都抓到内存中,而不是一次抓到一行?
SELECT *
表示您正在检索所有列。没有SELECT
子句(或其他类型的约束)的WHERE
意味着您正在检索所有行。因此,SELECT * FROM tasks
将尝试将整个表内容检索到内存中。
您可以将@Transaction
添加到此函数,因为这可能有助于克服此错误。引用the documentation:
在具有SELECT语句的
Query
方法上使用时,为Query
生成的代码将在事务中运行。在两种主要情况下,您可能需要这样做:
- 如果查询结果相当大,则最好在事务内运行它以接收一致的结果。否则,如果查询结果不适合单个
CursorWindow
,则由于游标窗口交换之间的数据库更改,查询结果可能会损坏。- 如果查询结果是带有
Relation
字段的POJO,则将分别查询这些字段。为了在这些查询之间获得一致的结果,您还希望在单个事务中运行它们。
更好的做法是不将整个表的内容加载到内存中(然后将整个表的行转换为实体对象)。堆空间有限。
为什么只有Android 9?
不知道。我不会担心的-如果您专注于检索较少的数据,那将为所有用户带来好处。