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 选择同一行似乎该行根本没有更新。