android数据集大小,Android:在ContentProvider中处理非常大的数据集以避免内存限制...

我使用ContentProvider查询数据库并返回CursorLoader中使用的Cursor:

ItemsActivity:

public class ItemsActivity extends SherlockActivity implements LoaderCallbacks {

@Override

public void onCreate(Bundle savedInstance) {

....

getSupportLoaderManager().initLoader(LOADER_ID, null, this);

...

}

@Override

public Loader onCreateLoader(int loaderId, Bundle bundle) {

return new CursorLoader(getApplicationContext(), itemsListUri, ...);

}

...

}

ItemsContentProvider:

public Cursor query(Uri uri, String[] projection, String selection, ...) {

SqliteQueryBuilder builder = new SqliteQueryBuilder();

builder.setTables(ItemsTable.NAME);

return builder.query(db, projection, selection, ...);

}

该活动有一个ListView,我使用CursorAdapter(通过LoaderCallbacks更新)来表示游标中的数据.

这工作正常,直到我需要查找大型数据集中的项目(例如,超过30,000行).观察日志我发现查找超出了内存限制,并且从结果游标中删除了一些行.

我的问题:在使用这样的游标时,处理非常大的数据集的最佳方法是什么?

我目前的解决方案是将ContentProvider中的SQLite查询拆分为具有偏移和限制的一系列查询,然后使用MergeCursor类组合这些查询:

private static final int LIMIT = 5000;

// Ignoring projection, selection, etc for simplicity here

public Cursor query(Uri uri, String projection, String selection, ...) {

List 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 cursors) {

if (cursors.size() == 1) {

return cursors.get(0);

}

return new MergeCursor(toCursorsArray(cursors));

}

这将加载所有数据,但是第一次执行查找时会有很长的延迟.执行多个查询时,列表视图为空约5秒钟.

请注意,当我尝试单个查找(而不是批量查找)时,加载几乎是即时的,尽管在达到内存限制时滚动列表时会有轻微的暂停.

所以:

使用单个查询:快速列表视图更新,但滚动暂停和内存限制已达到.

使用批处理查询:慢速列表视图更新,但滚动顺畅且没有达到内存限制.

我想知道是否有更好的解决方案可以快速更新列表视图,但是在滚动列表时也会根据需要获取更多数据.

Android 4.2.1,Nexus 7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值