我有一個自定義的遊標適配器,並且我想將光標的每個「行」傳遞迴應用程序(通過註冊的回調正在工作)。如何克隆或凍結Android數據庫光標
我知道我可以讀取光標中的每個字段並手動執行,但我只是想將光標的「凍結克隆」傳遞回來。 (讀取適配器中的字段將需要我製作這個類的幾個專用版本。)
理想情況下,我想回傳一些與Cursor具有相同接口但不能遍歷結果集的東西。
查詢返回的行少於20行,所以空間不是問題。
我有一個自定義的遊標適配器,並且我想將光標的每個「行」傳遞迴應用程序(通過註冊的回調正在工作)。如何克隆或凍結Android數據庫光標
我知道我可以讀取光標中的每個字段並手動執行,但我只是想將光標的「凍結克隆」傳遞回來。 (讀取適配器中的字段將需要我製作這個類的幾個專用版本。)
理想情況下,我想回傳一些與Cursor具有相同接口但不能遍歷結果集的東西。
查詢返回的行少於20行,所以空間不是問題。
我想你有一個20行的遊標,現在你想用一個只包含一行的遊標來調用一個方法20次。這裏是你如何能做到這一點:
Cursor c = ...;// contains many rows
if(c.moveToFirst()){
String[] columns = c.getColumnNames();
while(!c.isAfterLast()){
MatrixCursor newCursor = new MatrixCursor(columns , 1);
MatrixCursor.RowBuilder b = newCursor.newRow();
for(String col: columns){
// in case all columns are of string type. But if they are
// different then see my comment below
b.add(c.getString(c.getColumnIndex(col)));
}
// invoke your listener here with newCursor
}
}
如果列的數據類型不是字符串?
對於API> = 11:只需在for
循環中調用getType()
方法並使用switch
語句來調用適當的get方法。
對於API < 11:運行類似於此PRAGMA table_info(my_table_name)
的另一個查詢,然後只填寫Map
的列名和類型,並將其用於for循環。這裏是你如何閱讀這個遊標https://stackoverflow.com/a/9354401/1112882
這是一個有趣的方法 - 它是否適用於非字符串列的查詢? – fadedbee
是的,它絕對有效。你所要做的就是調用適當的'get'方法。但是對於這種方法,你必須知道單元的數據類型。如果你的最小目標是11,你可以在'for'循環中調用'getType()'並添加'switch'語句。 http://developer.android.com/reference/android/database/Cursor。html#getType(int) –
對於API級別<11,似乎有一種獲取列類型的方法。檢查http://stackoverflow.com/a/6298521/1112882 –
考慮你有一個名爲data的遊標,並且遊標有「title」和「author」列,並且這兩列都有字符串值。以下代碼顯示瞭如何將光標命名數據複製到名爲matrixCursor的遊標。
String[] PROJECTION = new String[]{"title","author"};
MatrixCursor matrixCursor = new MatrixCursor(PROJECTION);
int i = data.getColumnCount();
if (data.moveToFirst()) {
do {
Object[] currRow = new Object[i];
currRow[0] = data.getString(0);
currRow[1] = data.getString(1);
matrixCursor.addRow(currRow);
} while (data.moveToNext());
}
基於Anand's answer,這應該不必指定列名/投影工作:
public static Cursor cloneCursor(Cursor oldCursor) {
if (oldCursor == null) {
return null;
}
else {
/**
* Remember the cursor position
*/
int originalCursorPosition = oldCursor.getPosition();
String[] projection = oldCursor.getColumnNames();
MatrixCursor newCursor = new MatrixCursor(projection);
int numColumns = oldCursor.getColumnCount();
while (oldCursor.moveToNext()) {
/**
* Create the new row object
*/
Object[] newRow = new Object[numColumns];
/**
* Populate each column in the new row
*/
for (int columnIndex = 0; columnIndex < numColumns; columnIndex++) {
/**
* Detect the field type
*/
int fieldType = oldCursor.getType(columnIndex);
/**
* Use the field type to populate the row correctly
*/
if (fieldType == Cursor.FIELD_TYPE_BLOB) {
newRow[columnIndex] = oldCursor.getBlob(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_FLOAT) {
newRow[columnIndex] = oldCursor.getDouble(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_INTEGER) {
newRow[columnIndex] = oldCursor.getLong(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_STRING) {
newRow[columnIndex] = oldCursor.getString(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_NULL) {
newRow[columnIndex] = null;
}
else {
throw new RuntimeException("Unknown fieldType (" + fieldType + ") for column" + columnIndex);
}
}
/**
* Add the new row to the new cursor
*/
newCursor.addRow(newRow);
}
/**
* Move both cursors to the position that oldCursor was in before this method was called
*/
oldCursor.moveToPosition(originalCursorPosition);
newCursor.moveToPosition(originalCursorPosition);
/**
* Return the cloned cursor
*/
return newCursor;
}
}
UPDATE
getInt(...)
改爲getLong(...)
。
getFloat(...)
改爲getDouble(...)
你什麼冰凍克隆意思? –
@ M-WaJeEh我想要一個對象,它看起來像'getInt()'的'Cursor'等,但它無法移動到結果集的其他行。 – fadedbee
您可以在M-WaJeEh的答案中使用'MatrixCursor',或者您可以簡單地使用包含在您自己實現的'CursorWrapper'(您將通過回調函數)中的當前'Cursor'。爲了使'Cursor'凍結,你需要覆蓋'CursorWrapper'中的所有'moveXXX'方法,從而不做任何事情。 'CursorWrapper'也實現'Cursor'接口,所以你可以得到所有'Cursor'的方法。 – Luksprog