1

ウィジェットやサービスなど、さまざまなスレッドやプロセスから sqlite データベースを使用する Android アプリケーションを開発しています。

シングルトン パターンを使用して接続を許可すると、ランダムにこのエラーが発生します。アプリがメソッド内でスタックしたままにgetWriteableDatabase()なり、この警告がログに表示されます

W/SQLiteConnectionPool( 2021): The connection pool for database '/data/data/xyz' has been unable to grant a connection to thread xyz (xyz) with flags 0x1 for xyz seconds.
W/SQLiteConnectionPool( 2021): Connections: 0 active, 1 idle, 0 available.

このエラーは通常、アプリを閉じてから再度開くと数時間後に発生しますが、このバグを再現する正式な方法はありません。

私はこの両方のアプローチを使用しようとしましたが、幸運ではありませんでした:

class DB extends SQLiteOpenHelper {

    DB databaseHelper;
    SQLiteDatabase database;

    /**
     * Open a Database Helper.
     *
     * @param c the Context used to open the Database.
     * @return the Database Helper.
     */
    public static DB getInstance(final Context c) {
        if (databaseHelper == null) {
            databaseHelper = new DB(c.getApplicationContext());
        }
        return databaseHelper;
    }

    int active_connections;

    /**
     * @return the Database connection to use
     * @see closeReadableDataBase()
     */
    public synchronized SQLiteDatabase getDatabase() {
        if (database == null || !database.isOpen()) {
            if(database!=null) database.close();
            database = getWritableDatabase();
            active_connections=0;
            database.setLockingEnabled(false);
            TransitionHelper.execSQL(database, "PRAGMA read_uncommitted = true;");
            TransitionHelper.execSQL(database, "PRAGMA synchronous=OFF;");
        }
        active_connections++;
        return database;
    }

    /**
     * Closes the database connection.
     * @see openDatabaseForRead()
     */
    public synchronized void closeDatabase() {
        active_connections--;
        if(active_connections==0 && database!=null){
            database.close();
            database=null;
        }
    }
}

と:

class DB extends SQLiteOpenHelper {

    DB databaseHelper;
    SQLiteDatabase database;

    public static DB getInstance(final Context c) {
        if (databaseHelper == null) {
            databaseHelper = new DB(c.getApplicationContext());
        }
        return databaseHelper;
    }

    public synchronized SQLiteDatabase getDatabase() {
        if (database == null || !database.isOpen()) {
            if(database!=null) database.close();
            database = getWritableDatabase();
        }
        return database;
    }

    public synchronized void closeDatabase() {
        if(database!=null){
            database.close();
       }
    }
}
4

1 に答える 1

1

さまざまなプロセスから SQL データベースを使用している場合は、それをコンテンツ プロバイダーにカプセル化することを検討する必要があります。コンテンツ プロバイダーはローダーと連携して、プロセスや DataObserver などにまたがるアクセスを容易にします。それらを作成するための API ガイドもあります:コンテンツ プロバイダーの作成

于 2013-03-07T20:16:31.407 に答える