在Android多线程应用程序中正确使用yieldIfContendedSafely()

时间:2011-02-18 02:04:18

标签: android multithreading android-sqlite

在我的应用程序中,我使用AsyncTask将一些数据写入事务中的数据库。也可以从UI线程访问此数据库。在查看可用的数据库方法时,我遇到了yieldIfContendedSafely()。看起来这个方法应该用于从单独的线程进行事务的任何情况。但除了以下内容之外,几乎没有关于此方法的任何文档:

  

暂时结束事务以允许其他线程运行。到目前为止,该交易被认为是成功的。在打电话之前不要打电话给setTransactionSuccessful。返回时,将创建一个新事务但未标记为成功。这假定没有嵌套事务(beginTransaction只被调用一次),如果不是这样,则会抛出异常。

以下是我假设您将从线程中使用此方法的方法:

        try {
        db.beginTransaction();
        //insert some stuff into the database here 
        ...



        // is this how you use this method?
        boolean yielded = db.yieldIfContendedSafely();
        if (yielded) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }



        db.setTransactionSuccessful();
    } catch (SQLException e) {
        return false;
    } finally {
        db.endTransaction();
        db.close();
    }

这是使用此方法的正确方法吗?是否可以在同一个事务中多次使用db.yieldIfContendedSafely(),在多次写入数据库中的不同表之间?有什么建议吗?

1 个答案:

答案 0 :(得分:6)

从Android库中提取一些示例代码似乎太多比使用它更简单......

这取自com.android.providers.calendar.SQLiteContentProvider.java

@Override
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;
}

同时查看函数本身的源代码,看来,如果屈服,调用将在任何情况下推迟执行你的线程。