Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何克隆或冻结Android数据库光标_Android_Database_Sqlite_Cursor_Clone - Fatal编程技术网

如何克隆或冻结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的,似乎有一种获取列类型的方法。检查此方法比我之前的评论要好得多。我给了这个答案赏金,尽管看起来我所寻找的似乎不存在——一个简单的“行”类型,可以查询它的字段值。