Правильное использование yieldIfContendedSafely () в многопоточном приложении Android - PullRequest
7 голосов
/ 18 февраля 2011

В моем приложении я использую AsyncTask для записи некоторых данных в базу данных в транзакции.Эта база данных также доступна из потока пользовательского интерфейса.Просматривая доступные методы базы данных, я наткнулся на 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 Ответ

6 голосов
/ 12 мая 2011

Извлечение примера кода из библиотек 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;
}

Также, глядя на исходный код самой функции, кажется, что, если он будет получен, вызов в любом случае отложит выполнение вашего потока на короткий период.

...