Joh*_*zen 2 sqlite android android-contentprovider android-cursorloader
我使用a ContentProvider
来查询数据库并返回一个Cursor
用于CursorLoader
:
ItemsActivity:
public class ItemsActivity extends SherlockActivity implements LoaderCallbacks<Cursor> {
@Override
public void onCreate(Bundle savedInstance) {
....
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
...
}
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
return new CursorLoader(getApplicationContext(), itemsListUri, ...);
}
...
}
Run Code Online (Sandbox Code Playgroud)
ItemsContentProvider:
public Cursor query(Uri uri, String[] projection, String selection, ...) {
SqliteQueryBuilder builder = new SqliteQueryBuilder();
builder.setTables(ItemsTable.NAME);
return builder.query(db, projection, selection, ...);
}
Run Code Online (Sandbox Code Playgroud)
活动有一个ListView
,我使用CursorAdapter
(通过更新LoaderCallbacks
)来表示光标内的数据.
这工作正常,直到我需要查找大型数据集中的项目(例如,超过30,000行).观察日志我发现查找超出了内存限制,并且从结果游标中删除了一些行.
我的问题:在使用这样的游标时,处理非常大的数据集的最佳方法是什么?
我目前的解决方案是将SQLite查询ContentProvider
拆分为具有偏移和限制的查询序列,然后使用MergeCursor
类组合这些查询:
private static final int LIMIT = 5000;
// Ignoring projection, selection, etc for simplicity here
public Cursor query(Uri uri, String projection, String selection, ...) {
List<Cursor> cursors = newList();
int offset = 0;
Cursor c = db.rawQuery("select * from items limit " + LIMIT + " offset " + offset, null);
while (c.getCount() > 0) {
cursors.add(c);
offset += c.getCount();
c = db.rawQuery("select * from items limit " + LIMIT + " offset " + offset, null);
}
return createMergedCursor(cursors);
}
private Cursor createMergedCursors(List<Cursor> cursors) {
if (cursors.size() == 1) {
return cursors.get(0);
}
return new MergeCursor(toCursorsArray(cursors));
}
Run Code Online (Sandbox Code Playgroud)
这将加载所有数据,但是第一次执行查找时会有很长的延迟.执行多个查询时,列表视图为空约5秒钟.
请注意,当我尝试单个查找(而不是批量查找)时,加载几乎是即时的,尽管在达到内存限制时滚动列表时会有轻微的暂停.
所以:
使用单个查询:快速列表视图更新,但滚动暂停和内存限制已达到.
使用批处理查询:慢速列表视图更新,但滚动顺畅且没有达到内存限制.
我想知道是否有更好的解决方案可以快速更新列表视图,但是在滚动列表时也会根据需要获取更多数据.
Android 4.2.1,Nexus 7
移动设备不是为处理这些数据量而设计的.
但是,如果您确实想要在可怜的用户上创建如此大的滚动列表,则可以将其设计为虚拟列表,其中只根据需要加载条目; 请参阅Android Endless List.
注意:使用该OFFSET
子句效率低下; 有关详细信息,请参阅滚动光标.
归档时间: |
|
查看次数: |
6946 次 |
最近记录: |