我已经在我的应用程序中实现了这一点,这是我使用的代码的要点。
在我的内容提供程序中,我重写了 applyBatch() 方法,这是一个非常简单的重写方法:
/**
* Performs the work provided in a single transaction
*/
@Override
public ContentProviderResult[] applyBatch(
ArrayList<ContentProviderOperation> operations) {
ContentProviderResult[] result = new ContentProviderResult[operations
.size()];
int i = 0;
// Opens the database object in "write" mode.
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
// Begin a transaction
db.beginTransaction();
try {
for (ContentProviderOperation operation : operations) {
// Chain the result for back references
result[i++] = operation.apply(this, result, i);
}
db.setTransactionSuccessful();
} catch (OperationApplicationException e) {
Log.d(TAG, "batch failed: " + e.getLocalizedMessage());
} finally {
db.endTransaction();
}
return result;
}
因为要支持反向引用,所以将结果提供给下一步操作。当我实际上想在这个事务中更改数据库中的内容时,我循环遍历我的内容并执行如下操作:
operations.add(ContentProviderOperation
.newInsert(
Uri.withAppendedPath(
NotePad.Notes.CONTENT_ID_URI_BASE,
Long.toString(task.dbId)))
.withValues(task.toNotesContentValues(0, listDbId))
.build());
// Now the other table, use back reference to the id the note
// received
noteIdIndex = operations.size() - 1;
operations.add(ContentProviderOperation
.newInsert(NotePad.GTasks.CONTENT_URI)
.withValues(task.toGTasksContentValues(accountName))
.withValueBackReferences(
task.toGTasksBackRefContentValues(noteIdIndex))
.build());
您只需要记住通过调用来完成:
provider.applyBatch(operations);
这将在单个事务中执行您的操作,并且如果您需要来自早期插入的 id 而没有问题,则支持反向引用。