The SQLite database is often used when developing Android programs, and the exception occurs when accessing the database in multiple threads: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:
This kind of exception information, Sqlite itself does not support multi-threaded simultaneous operation, below we give a solution and list some of the code used in the project.
We'll use the Atomicinteger, a class that provides an integer for atomic manipulation. Because Android relies on a powerful JDK when used, the Synchronized keyword will inevitably be used. and Atomicinteger through a thread-safe addition and subtraction operation interface, so we can do a databasemanager such a class, the specific code see the following code block:
Public classDatabasemanager {PrivateAtomicinteger Mopencounter =NewAtomicinteger (); Private StaticDatabasemanager instance; Private StaticSqliteopenhelper Mdatabasehelper; Privatesqlitedatabase mdatabase; Public Static synchronized voidinitializeinstance (Sqliteopenhelper helper) {if(Instance = =NULL) {instance=NewDatabasemanager (); Mdatabasehelper=Helper; } } Public Static synchronizedDatabasemanager getinstance (Sqliteopenhelper helper) {if(Instance = =NULL) {initializeinstance (helper); } returninstance; } Public synchronizedsqlitedatabase getwritabledatabase () {if(Mopencounter.incrementandget () = = 1) { //Opening New DatabaseMdatabase =mdatabasehelper.getwritabledatabase (); } returnmdatabase; } Public synchronizedsqlitedatabase getreadabledatabase () {if(Mopencounter.incrementandget () = = 1) { //Opening New DatabaseMdatabase =mdatabasehelper.getreadabledatabase (); } returnmdatabase; } Public synchronized voidcloseDatabase () {if(Mopencounter.decrementandget () = = 0) { //Closing DatabaseMdatabase.close (); } }
When we close the database, we judge
Mopencounter.decrementandget () = = 0 (the current value of the field for the given object managed by the updater is 0) does not formally close the database until the above exception occurs.
In our Operations database logic code, use the following
The prime Minister wants to get
Mdatabasemanager = Databasemanager.getinstance (Mcontext);
Object
/*** * Determine if there is a value in the table*/ Public BooleanIsexisttabvalus () {BooleanFlag =false; Sqlitedatabase DB=mdatabasemanager.getreadabledatabase ();//Gets 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 Database}returnFlag; }
The above provides a usage method, now in the project to use this method about the database operation has never appeared concurrency problem, you can try.
Android SQLite multithreaded Access exception solution