7

私のアプリケーションでAsyncTaskは、トランザクションでデータベースにデータを書き込むために を使用しています。このデータベースは、UI スレッドからもアクセスされます。利用可能なデータベース メソッドを調べているうちに、yieldIfContendedSafely(). このメソッドは、トランザクションが別のスレッドから行われている場合に使用する必要があるようです。ただし、この方法に関するドキュメントは、次のものを除いてほとんどありません。

トランザクションを一時的に終了して、他のスレッドを実行できるようにします。これまでのところ、トランザクションは成功していると見なされます。setTransactionSuccessfulこれを呼び出す前に呼び出さないでください。これが返されると、新しいトランザクションが作成されますが、成功としてマークされません。これは、ネストされたトランザクションがない (1 回だけ呼び出された) ことを前提としており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()データベース内の異なるテーブルへの複数の書き込みの間に、同じトランザクションで複数回使用しても問題ありませんか? 助言がありますか?

4

1 に答える 1

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

また、関数自体のソース コードを調べると、呼び出しが発生した場合、どのような場合でもスレッドの実行が短時間延期されるようです。

于 2011-05-12T11:14:39.173 に答える