Я реализовал это в своем приложении, и вот суть кода, который я использую.
В моем поставщике контента я переопределил метод 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);
Это будет выполнять ваши вещи в одной транзакции и поддерживает обратные ссылки, если вам нужен идентификатор из более ранней вставки без проблем.