@ jcwenger Сначала, после прочтения вашего поста, я думаю, что причина массового вставления быстрее, чем ApplyBatch, но после прочтения кода поставщика контактов, я так не думаю.1. Вы сказали, что ApplyBatch используют транзакции, да, но bulkInsert также использует транзакции.Вот код этого кода:
public int bulkInsert(Uri uri, ContentValues[] values) {
int numValues = values.length;
mDb = mOpenHelper.getWritableDatabase();
mDb.beginTransactionWithListener(this);
try {
for (int i = 0; i < numValues; i++) {
Uri result = insertInTransaction(uri, values[i]);
if (result != null) {
mNotifyChange = true;
}
mDb.yieldIfContendedSafely();
}
mDb.setTransactionSuccessful();
} finally {
mDb.endTransaction();
}
onEndTransaction();
return numValues;
}
То есть, массовая вставка также использует переводы. Так что я не думаю, что причина в этом.2. Вы сказали, что bulkInsert применяет целую кучу значений к одной и той же таблице. Извините, я не могу найти связанный код в исходном коде froyo. И я хочу знать, как вы можете найти это? Не могли бы вы сказать мне?
Причина, по которой я думаю, заключается в том, что:
bulkInsert использует mDb.yieldIfContendedSafely (), тогда как applyBatch использует mDb.yieldIfContendedSafely (SLEEP_AFTER_YIELD_DELAY) / * SLEEP_AFTER_YIELD *4000* * * * * * *код SQLiteDatabase.java, я нахожу, что, если установить время в yieldIfContendedSafely, он будет спать, но если вы не установите время, он не будет спать. Вы можете обратиться к приведенному ниже коду, который является частьюкода SQLiteDatabase.java
private boolean yieldIfContendedHelper(boolean checkFullyYielded, long sleepAfterYieldDelay) {
if (mLock.getQueueLength() == 0) {
// Reset the lock acquire time since we know that the thread was willing to yield
// the lock at this time.
mLockAcquiredWallTime = SystemClock.elapsedRealtime();
mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
return false;
}
setTransactionSuccessful();
SQLiteTransactionListener transactionListener = mTransactionListener;
endTransaction();
if (checkFullyYielded) {
if (this.isDbLockedByCurrentThread()) {
throw new IllegalStateException(
"Db locked more than once. yielfIfContended cannot yield");
}
}
if (sleepAfterYieldDelay > 0) {
// Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to
// check if anyone is using the database. If the database is not contended,
// retake the lock and return.
long remainingDelay = sleepAfterYieldDelay;
while (remainingDelay > 0) {
try {
Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ?
remainingDelay : SLEEP_AFTER_YIELD_QUANTUM);
} catch (InterruptedException e) {
Thread.interrupted();
}
remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM;
if (mLock.getQueueLength() == 0) {
break;
}
}
}
beginTransactionWithListener(transactionListener);
return true;
}
Я думаю, что причина в том, что bulkInsert работает быстрее, чем applyBatch.
Любой вопрос, пожалуйста, свяжитесь со мной.