0

ContentProvider 中 SQLite 更新的奇怪行为。

更新方法:

@Override
public int update(Uri uri, ContentValues updateValues, String whereClause, String[] whereValues) {

    SQLiteDatabase db = TasksContentProvider.dbHelper.getWritableDatabase();
    int updatedRowsCount;
    String finalWhere;

    db.beginTransaction();
    // Perform the update based on the incoming URI's pattern
    try {
        switch (uriMatcher.match(uri)) {
        case MATCHER_TASKS:

                updatedRowsCount = db.update(TasksTable.TABLE_NAME, updateValues, whereClause, whereValues);
                break;

        case MATCHER_TASK:
                String id = uri.getPathSegments().get(TasksTable.TASK_ID_PATH_POSITION);
                finalWhere = TasksTable._ID + " = " + id;

                // if we were passed a 'where' arg, add that to our 'finalWhere'
                if (whereClause != null) {
                    finalWhere = finalWhere + " AND " + whereClause;
                }
                updatedRowsCount = db.update(TasksTable.TABLE_NAME, updateValues, finalWhere, whereValues);
                break;

        default:
                // Incoming URI pattern is invalid: halt & catch fire.
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    } finally {
        db.endTransaction();
    }

    if (updatedRowsCount > 0) {
        DVSApplication.getContext().getContentResolver().notifyChange(uri, null);
    }

    return updatedRowsCount;
}

查询方法:

    @Override
    public Cursor query(Uri uri, String[] selectedColumns, String whereClause, String[] whereValues, String sortOrder) {

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        // Choose the projection and adjust the "where" clause based on URI pattern-matching.
        switch (uriMatcher.match(uri)) {
        case MATCHER_TASKS:
            qb.setTables(TasksTable.TABLE_NAME);
            qb.setProjectionMap(tasksProjection);
            break;

        // asking for a single comic - use the rage comics projection, but add a where clause to only return the one
        // comic
        case MATCHER_TASK:
            qb.setTables(TasksTable.TABLE_NAME);
            qb.setProjectionMap(tasksProjection);

            // Find the comic ID itself in the incoming URI
            String taskId = uri.getPathSegments().get(TasksTable.TASK_ID_PATH_POSITION);
            qb.appendWhere(TasksTable._ID + "=" + taskId);
            break;
        case MATCHER_TASK_COMMENTS:
            qb.setTables(TaskCommentsTable.TABLE_NAME);
            qb.setProjectionMap(taskCommentsProjection);
            break;

        case MATCHER_TASK_COMMENT:
            qb.setTables(TaskCommentsTable.TABLE_NAME);
            qb.setProjectionMap(taskCommentsProjection);

            String commentId = uri.getPathSegments().get(TaskCommentsTable.TASK_COMMENT_ID_PATH_POSITION);
            qb.appendWhere(TaskCommentsTable._ID + "=" + commentId);
            break;
        default:
            // If the URI doesn't match any of the known patterns, throw an exception.
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        SQLiteDatabase db = TasksContentProvider.dbHelper.getReadableDatabase();
        // the two nulls here are 'grouping' and 'filtering by group'
        Cursor cursor = qb.query(db, selectedColumns, whereClause, whereValues, null, null, sortOrder);

        // Tell the Cursor about the URI to watch, so it knows when its source data changes
        cursor.setNotificationUri(DVSApplication.getContext().getContentResolver(), uri);

        return cursor;
    }

试图更新和行。

int affectedRowsCount = provider.update(Uri.parse(TasksTable.CONTENT_URI.toString() + "/"+ taskId), task.getContentValues(), null, null);

affectedRowsCount等于 1

检查行是否已更新

Cursor cs = provider.query(TasksTable.CONTENT_URI, new String[] {TasksTable.TASK_STATE_VALUE}, TasksTable._ID +" = ?", new String[] {String.valueOf(taskId)}, null);
if(cs.moveToFirst()) {
    String state = cs.getString(cs.getColumnIndex(TasksTable.TASK_STATE_VALUE));
}

state和更新前一样。尽管更新成功是因为affectedRowsCount等于 1,但是通过相同的 id 选择同一行似乎该行根本没有更新。

4

1 回答 1

1

在您的update方法中,您使用的是 a transaction,但您从未将结果设置为成功,因此每次达到db.endTransaction()a时rollback都会执行。这就是不存储您的更新的原因。

如果任何事务在未标记为干净的情况下结束(通过调用 setTransactionSuccessful),则更改将回滚。否则他们将被承诺。

你需要使用

db.setTransactionSuccessful();

当您的更新完成且没有错误时。在您的代码中,它应该在您的db.update.

于 2013-07-31T11:22:20.340 回答