如何克隆或冻结Android数据库光标
我有一个自定义游标适配器,我希望将游标的每一行都传递回应用程序(通过一个正在工作的注册回调) 我知道我可以从游标中读取每个字段并手动执行,但我只想将游标的“冻结克隆”传递回去。(阅读适配器中的字段需要我制作该类的几个专门版本。) 理想情况下,我希望传回与游标具有相同接口的内容,但无法遍历结果集如何克隆或冻结Android数据库光标,android,database,sqlite,cursor,clone,Android,Database,Sqlite,Cursor,Clone,我有一个自定义游标适配器,我希望将游标的每一行都传递回应用程序(通过一个正在工作的注册回调) 我知道我可以从游标中读取每个字段并手动执行,但我只想将游标的“冻结克隆”传递回去。(阅读适配器中的字段需要我制作该类的几个专门版本。) 理想情况下,我希望传回与游标具有相同接口的内容,但无法遍历结果集 查询返回的行数少于20行,因此空间不是问题。我猜您有一个包含20行的游标,现在您希望使用仅包含一行的游标调用一个方法20次。以下是如何做到这一点: Cursor c = ...;// contains m
查询返回的行数少于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,假设您有一个名为data的游标,游标有“title”和“author”列,这两列都有字符串值。下面的代码显示了如何将名为cursor的数据复制到名为matrixCursor的cursor
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());
}
基于,这应该可以工作,而不必指定列名/投影:
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;
}
}
公共静态游标克隆器(游标oldCursor){
如果(oldCursor==null){
返回null;
}
否则{
/**
*记住光标的位置
*/
int originalCursorPosition=oldCursor.getPosition();
String[]projection=oldCursor.getColumnNames();
MatrixCursor newCursor=新MatrixCursor(投影);
int numColumns=oldCursor.getColumnCount();
while(oldCursor.moveToNext()){
/**
*创建新行对象
*/
Object[]newRow=新对象[numColumns];
/**
*填充新行中的每一列
*/
对于(int columnIndex=0;columnIndex
更新
getInt(…)
更改为getLong(…)
getFloat(…)
改为getDouble(…)
你说的冻结克隆是什么意思?@M-WaJeEh我想要一个对象,它看起来像getInt()
等的光标。,但是它不能移动到结果集的其他行。您可以使用M-WaJeEh在回答中所说的矩阵Xcersor
,或者您可以简单地使用当前游标
,它包装在您自己的游标包装器
实现中(您将通过回调)。为了使光标
冻结,您需要覆盖光标包装
中的所有moveXXX
方法,而不执行任何操作CursorWrapper
还实现了Cursor
接口,因此您可以获得Cursor
的所有方法。这是一种有趣的方法-它适用于具有非字符串列的查询吗?是的,它绝对有效。您所要做的就是调用适当的get
方法。但是对于这种方法,您必须知道单元格的数据类型。如果最小目标为11,则可以在for
循环中调用getType()
,然后添加switch
语句。对于API级别<11的,似乎有一种获取列类型的方法。检查此方法比我之前的评论要好得多。我给了这个答案赏金,尽管看起来我所寻找的似乎不存在——一个简单的“行”类型,可以查询它的字段值。