Android Sqlite multi-thread access exception solution, androidsqlite
Sqlite databases are frequently used when developing Android programs. This exception occurs when multiple threads access the database: java. lang. illegalStateException: Cannot perform this operation because the connection pool has been closed.Or java. lang. IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: or java. lang. IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
Sqlite itself does not support multi-threaded operations at the same time. Next we will provide a solution and list the code used in some projects.
We will use AtomicInteger, a class that provides atomic operations for Integer. Android uses the synchronized keyword when using the powerful jdk. While AtomicInteger uses a thread-safe addition/subtraction operation interface, we can create a class such as DatabaseManager. For specific code, see the following code block:
public class DatabaseManager { private AtomicInteger mOpenCounter = new AtomicInteger(); private static DatabaseManager instance; private static SQLiteOpenHelper mDatabaseHelper; private SQLiteDatabase mDatabase; public static synchronized void initializeInstance(SQLiteOpenHelper helper) { if (instance == null) { instance = new DatabaseManager(); mDatabaseHelper = helper; } } public static synchronized DatabaseManager getInstance(SQLiteOpenHelper helper) { if (instance == null) { initializeInstance(helper); } return instance; } public synchronized SQLiteDatabase getWritableDatabase() { if(mOpenCounter.incrementAndGet() == 1) { // Opening new database mDatabase = mDatabaseHelper.getWritableDatabase(); } return mDatabase; } public synchronized SQLiteDatabase getReadableDatabase() { if(mOpenCounter.incrementAndGet() == 1) { // Opening new database mDatabase = mDatabaseHelper.getReadableDatabase(); } return mDatabase; } public synchronized void closeDatabase() { if(mOpenCounter.decrementAndGet() == 0) { // Closing database mDatabase.close(); } }
Judge when we close the database
When mOpenCounter. decrementAndGet () = 0 (the current value of the field of the given object managed by the Updater is 0), the database will be officially closed without the above exception.
In the logic code of the database, we use
The Prime Minister wants to obtain
mDatabaseManager = DatabaseManager.getInstance(mContext);
Object
/***** Determine whether the table has a value */public boolean isExistTabValus () {boolean flag = false; SQLiteDatabase db = mDatabaseManager. getReadableDatabase (); // obtain a readable database object Cursor curcor = null; try {curcor = db. rawQuery ("select * from tab", null); while (curcor. moveToNext () {if (curcor. getCount ()> 0) {flag = true ;}} catch (Exception e) {Log. e (TAG, "isExistTabValus error");} finally {if (curcor! = Null) {curcor. close () ;}mdatabasemanager. closeDatabase (); // close the database} return flag ;}
The above provides a usage method. Currently, using this method in projects has never encountered any concurrency issues concerning database operations. You can try it.