[Android] Best way to open/close a database in multi-threaded?


#1

I’m having trouble opening / closing the database, read/write in multithreaded to process data on Android.
So what’s the best way to deal with it?

My class :

public class CipherManager {

    public static final String DATABASE_NAME = "encypteddb.sqlite";
    private SQLiteDatabase database;
    private final File databaseFile;

    private static CipherManager instance;

    private String key;

    private CipherManager() {
        key = getKey();
        databaseFile = ApplicationController.getInstance().getDatabasePath(DATABASE_NAME);
        database = SQLiteDatabase.openOrCreateDatabase(databaseFile, key, null);
    }

    private String getKey() {
        try {
            RSACipher cipher = new RSACipher();
            return cipher.decrypt(getPassword());
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | IOException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String getPassword() {
        return "dlasdjlakdj";
    }

    public synchronized static CipherManager getInstance() {
        if (instance == null) {
            instance = new CipherManager();
        }
        return instance;
    }

    public synchronized SQLiteDatabase getDatabase() {
        if (!database.isOpen()) {
            database = SQLiteDatabase.openDatabase(databaseFile.getPath(), key, null, SQLiteDatabase.OPEN_READWRITE);
        }
        return database;
    }

    public synchronized void close(){
        if (database.isOpen()){
            database.close();
        }
    }

    public void setDatabase(SQLiteDatabase database) {
        this.database = database;
    }
}

#2

Hi @chihung93

SQLCipher for Android is compiled with -DSQLITE_THREADSAFE, however while the wrapping Java library contains some threading primitives for certain operations, is not entirely thread safe. It is recommended that you include a synchronization mechanism to allow for coordinated access to your connection.


#3

Hello @developernotes

I often get “System.err: java.lang.IllegalStateException: database not open” when I run on multithread.
Do u have any suggestion for solve this problem?


#4

Hi @chihung93

We would recommend utilizing a synchronization mechanism to coordinate access to your connection. Within this function that provides the database connection, you can guard the connection instance to verify it is not null and open before returning.