Android 9(仅观察到)使用 Room(对于非图像):行太大而无法放入 CursorWindow requiredPos=0,totalRows=1
Android 9(only observed) using Room(for non-images): Row too big to fit into CursorWindow requiredPos=0, totalRows=1
我只在 Android 9 上观察到这一点,而且可能只在三星设备上观察到过。我将对多个序列化字符串的多个 JSON 响应存储到我的数据库中,稍后再次使用 Moshi 将类型转换为模型。
导致此错误的查询是:
@Query(“SELECT * FROM tasks”)
public abstract Flowable<List<TaskEntity>> getAll();
最后一个实例在 table 中共有约 392,000 个字符。这些实际上在 table.
中分成大约 5500 个字符大小的条目
- 为什么游标对 ~11k 字节大小的条目有问题?我选择 * 是否意味着光标将整个 table 抓取到内存中,而不是一次抓取一行?
- 为什么只有 Android 9 个?
谢谢。
Does the fact that I'm selecting * mean the cursor is grabbing the whole table into memory and not a single row at a time?
SELECT *
表示您正在检索所有列。没有 WHERE
子句(或其他类型的约束)的 SELECT
意味着您正在检索所有行。因此,SELECT * FROM tasks
将尝试将整个 table 内容检索到内存中。
您可以将 @Transaction
添加到此函数,因为这可能有助于解决此错误。引用 the documentation:
When used on a Query
method that has a SELECT statement, the generated code for the Query
will be run in a transaction. There are 2 main cases where you may want to do that:
- If the result of the query is fairly big, it is better to run it inside a transaction to receive a consistent result. Otherwise, if the query result does not fit into a single
CursorWindow
, the query result may be corrupted due to changes in the database in between cursor window swaps.
- If the result of the query is a POJO with
Relation
fields, these fields are queried separately. To receive consistent results between these queries, you also want to run them in a single transaction.
更好的做法是不要将整个 table 的内容加载到内存中(然后将整个 table 的行转换为实体对象)。堆 space 是有限的。
Why only Android 9?
没有线索。我不会担心这一点 — 如果您专注于检索更少的数据,那将对您的所有用户都有好处。
我只在 Android 9 上观察到这一点,而且可能只在三星设备上观察到过。我将对多个序列化字符串的多个 JSON 响应存储到我的数据库中,稍后再次使用 Moshi 将类型转换为模型。
导致此错误的查询是:
@Query(“SELECT * FROM tasks”)
public abstract Flowable<List<TaskEntity>> getAll();
最后一个实例在 table 中共有约 392,000 个字符。这些实际上在 table.
中分成大约 5500 个字符大小的条目- 为什么游标对 ~11k 字节大小的条目有问题?我选择 * 是否意味着光标将整个 table 抓取到内存中,而不是一次抓取一行?
- 为什么只有 Android 9 个?
谢谢。
Does the fact that I'm selecting * mean the cursor is grabbing the whole table into memory and not a single row at a time?
SELECT *
表示您正在检索所有列。没有 WHERE
子句(或其他类型的约束)的 SELECT
意味着您正在检索所有行。因此,SELECT * FROM tasks
将尝试将整个 table 内容检索到内存中。
您可以将 @Transaction
添加到此函数,因为这可能有助于解决此错误。引用 the documentation:
When used on a
Query
method that has a SELECT statement, the generated code for theQuery
will be run in a transaction. There are 2 main cases where you may want to do that:
- If the result of the query is fairly big, it is better to run it inside a transaction to receive a consistent result. Otherwise, if the query result does not fit into a single
CursorWindow
, the query result may be corrupted due to changes in the database in between cursor window swaps.- If the result of the query is a POJO with
Relation
fields, these fields are queried separately. To receive consistent results between these queries, you also want to run them in a single transaction.
更好的做法是不要将整个 table 的内容加载到内存中(然后将整个 table 的行转换为实体对象)。堆 space 是有限的。
Why only Android 9?
没有线索。我不会担心这一点 — 如果您专注于检索更少的数据,那将对您的所有用户都有好处。