我习惯在 Android 中使用 Loader 和 CursorAdapter。查看适用于 Android 的 Couchbase-Lite,我看不到一种以我认为是内存友好的方式填充 ListView 的方法。
在此处查看示例应用程序中的代码: https ://github.com/couchbaselabs/GrocerySync-Android/blob/master/GrocerySync-Android/src/main/java/com/couchbase/grocerysync/MainActivity.java
protected void startCBLite() throws Exception {
manager = new Manager(getApplicationContext().getFilesDir(), Manager.DEFAULT_OPTIONS);
//install a view definition needed by the application
database = manager.getDatabase(DATABASE_NAME);
com.couchbase.lite.View viewItemsByDate = database.getView(String.format("%s/%s", designDocName, byDateViewName));
viewItemsByDate.setMap(new Mapper() {
@Override
public void map(Map<String, Object> document, Emitter emitter) {
Object createdAt = document.get("created_at");
if (createdAt != null) {
emitter.emit(createdAt.toString(), null);
}
}
}, "1.0");
startLiveQuery(viewItemsByDate);
startSync();
}
private void startSync() {
URL syncUrl;
try {
syncUrl = new URL(SYNC_URL);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
Replication pullReplication = database.createPullReplication(syncUrl);
pullReplication.setContinuous(true);
Replication pushReplication = database.createPushReplication(syncUrl);
pushReplication.setContinuous(true);
pullReplication.start();
pushReplication.start();
pullReplication.addChangeListener(this);
pushReplication.addChangeListener(this);
}
private void startLiveQuery(com.couchbase.lite.View view) throws Exception {
final ProgressDialog progressDialog = showLoadingSpinner();
if (liveQuery == null) {
liveQuery = view.createQuery().toLiveQuery();
liveQuery.addChangeListener(new LiveQuery.ChangeListener() {
@Override
public void changed(LiveQuery.ChangeEvent event) {
displayRows(event.getRows());
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
}
});
}
});
liveQuery.start();
}
}
private void displayRows(QueryEnumerator queryEnumerator) {
final List<QueryRow> rows = getRowsFromQueryEnumerator(queryEnumerator);
runOnUiThread(new Runnable() {
@Override
public void run() {
itemListViewAdapter = new GrocerySyncListAdapter(
getApplicationContext(),
R.layout.grocery_list_item,
R.id.label,
rows
);
itemListView.setAdapter(itemListViewAdapter);
itemListView.setOnItemClickListener(MainActivity.this);
itemListView.setOnItemLongClickListener(MainActivity.this);
}
});
}
private List<QueryRow> getRowsFromQueryEnumerator(QueryEnumerator queryEnumerator) {
List<QueryRow> rows = new ArrayList<QueryRow>();
for (Iterator<QueryRow> it = queryEnumerator; it.hasNext();) {
QueryRow row = it.next();
rows.add(row);
}
return rows;
}
@Override
public View getView(int position, View itemView, ViewGroup parent) {
...
QueryRow row = list.get(position);
Document document = row.getDocument();
...
}
查询返回一个枚举器,然后循环创建 ArrayList,然后将其传递给查询适配器。这一切都在 UI 线程上完成。
这对于一个简单的杂货店应用程序演示来说可能很好,但如果我的数据库中有 20,000 个文档,并且有 18,000 个文档响应我的查询,该怎么办?