《SQLite权威指南》上曾提到过,“我们的建议是要时刻记住:在那些只有3英寸到4英寸大小的屏幕上显示千行是不现实的。哪些用户才会在一次操作中滚动或读取如此大量的数据,特别是在这样小屏幕的设备上?”但如果业务提出需求需要显示如此大规模的数据,也许你会碰到与我们相似的问题,查询大型数据集太慢。如果使用了CursorAdapter,那么情况也许会更糟糕。
1.问题的起源
在一个包含了32000条记录的数据库表中查询读取30490条记录,生成 30490个Java对象,耗时13S。耗时太长且无法忍受。
SQL语句 select
colum1..colum 15 from table1 where type = 2 or type = 4;
如图1.1所示,业务代码只是简单的new一个对象,并且把每列的值读出来而已。图1
1.1时间花在哪了?
1.1.1 多次调用SQLiteQuery.fillWindow
SQLiteCursor通过CursorWindow管理数据。 CursorWindow实际上是对2MB内存进行封装,用于存放sqlite3数据里查询出的数据。当查询的数据集大于CursorWindow的容量时,Cursor将会多次执行fillWindow方法(详见第二章源码分析) 。SQliteQuery.fillWindow方法是从查询的数据集中提取数据放入CursorWindow中。
1.1.2 JNI间的数据转换
Java层的CursorWindow为Native层的CursorWindow的一个外壳,它记录了Native层CursorWindow的地址。因此cursor.getString()这些方法,实际上都是通过JNI把 C层的对象转换成java