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

**URL:** <https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646>\
**Category:** SQLCipher\
**Created:** [February 8, 2018, 7:27pm UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646 "2018-02-08T19:27:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chihung93](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@chihung93](https://discuss.zetetic.net/u/chihung93)\
**Post date:** [February 8, 2018, 7:27pm UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646/1 "2018-02-08T19:27:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)\
**Post date:** [February 8, 2018, 10:19pm UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646/2 "2018-02-08T22:19:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![chihung93](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@chihung93](https://discuss.zetetic.net/u/chihung93)\
**Post date:** [February 9, 2018, 1:57am UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646/3 "2018-02-09T01:57:03Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)\
**Post date:** [February 9, 2018, 3:06pm UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646/4 "2018-02-09T15:06:25Z")

</div>

Hi @chihung93

> [@chihung93](#):
>
> 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?

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.

---

<div class="post-metadata">

**Author:** ![hshahdoost](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/hshahdoost/32/1024_2.png) [@hshahdoost](https://discuss.zetetic.net/u/hshahdoost)\
**Post date:** [April 15, 2019, 10:36am UTC](https://discuss.zetetic.net/t/android-best-way-to-open-close-a-database-in-multi-threaded/2646/5 "2019-04-15T10:36:43Z")

</div>

Hi @chihung93  
This is not related to SQLCipher but rather to how you close your SQLiteDatabase instance. you should know that your SQLiteHelper uses the same instance if it is already open, So when you simply close one instance you are also closing all the other instances created in the lifetime of that instance.  
So the process of closing you SQLiteDatabase becomes a little trickier. I would personally recommend you count the references in SQLiteHelper and only close your database when there is no more reference attached to it.
