@jcwenger 起初,在阅读您的帖子后,我认为这是 bulkInsert 比 ApplyBatch 更快的原因,但在阅读了 Contact Provider 的代码后,我不这么认为。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;
}
也就是说,bulkInsert 也使用了转换。所以我认为不是这个原因。2.你说bulkInsert将一大堆值应用于同一张表。对不起,我在froyo的源代码中找不到相关代码。我想知道你是怎么找到的?你能告诉我吗?
我认为的原因是:
bulkInsert 使用 mDb.yieldIfContendedSafely() 而 applyBatch 使用 mDb.yieldIfContendedSafely(SLEEP_AFTER_YIELD_DELAY)/*SLEEP_AFTER_YIELD_DELAY = 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 更快的原因。
有任何问题请联系我。