android Sqlite多线程访问异常解决方案
16lz
2021-12-04
原文http://www.cnblogs.com/wangmars/p/4530670.html
在开发Android的程序的时候sqlite数据库是经常用到的;在多线程访问数据库的时候会出现这样的异常:java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.或java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: 或java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
这样的异常信息,Sqlite 自身是不支持多线程同时操作的,下面呢我们给出一个解决方案并列出一些项目中用到的代码。
我们会用到AtomicInteger,一个提供原子操作的Integer的类。因为Android 依托强大的jdk在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口,由此我们可以做一个DatabaseManager 这样的类,具体代码见下面的代码块:
publicclassDatabaseManager{privateAtomicIntegermOpenCounter=newAtomicInteger();privatestaticDatabaseManagerinstance;privatestaticSQLiteOpenHelpermDatabaseHelper;privateSQLiteDatabasemDatabase;publicstaticsynchronizedvoidinitializeInstance(SQLiteOpenHelperhelper){if(instance==null){instance=newDatabaseManager();mDatabaseHelper=helper;}}publicstaticsynchronizedDatabaseManagergetInstance(SQLiteOpenHelperhelper){if(instance==null){initializeInstance(helper);}returninstance;}publicsynchronizedSQLiteDatabasegetWritableDatabase(){if(mOpenCounter.incrementAndGet()==1){//OpeningnewdatabasemDatabase=mDatabaseHelper.getWritableDatabase();}returnmDatabase;}publicsynchronizedSQLiteDatabasegetReadableDatabase(){if(mOpenCounter.incrementAndGet()==1){//OpeningnewdatabasemDatabase=mDatabaseHelper.getReadableDatabase();}returnmDatabase;}publicsynchronizedvoidcloseDatabase(){if(mOpenCounter.decrementAndGet()==0){//ClosingdatabasemDatabase.close();}}
在我们进行关闭数据库的时候判断
mOpenCounter.decrementAndGet()==0(更新器管理的给定对象的字段的当前值为0)的时候才正式关闭数据库,就不会出现上述异常。用方式呢,在我们操作数据库逻辑代码中如下使用首相要取得
mDatabaseManager=DatabaseManager.getInstance(mContext);
对象
/****判断表中是否有值*/publicbooleanisExistTabValus(){booleanflag=false;SQLiteDatabasedb=mDatabaseManager.getReadableDatabase();//获取一个可读的数据库对象Cursorcurcor=null;try{curcor=db.rawQuery("select*fromtab",null);while(curcor.moveToNext()){if(curcor.getCount()>0){flag=true;}}}catch(Exceptione){Log.e(TAG,"isExistTabValuserror");}finally{if(curcor!=null){curcor.close();}mDatabaseManager.closeDatabase();//关闭数据库}returnflag;}
上面提供一个使用方法,现在项目中使用这种方法关于数据库的操作从未没有出现并发的问题,大家可以尝试一下。
更多相关文章
- android 如何让dialog不消失,即使是用户按了返回键dialog也不消
- android中的倒计时
- 如何在Android设备中用NDK编译SQLite并且对SQLite进行操作(增删)-H
- Android查询短信数据库 查询联系人数据库
- android 想要弹出另外界面操作步骤
- 818
- Android(安卓)避免Activity转场动画退出时候和系统自带的一起出
- Android(安卓)技巧:命令行运行 sqlite3
- Android(安卓)Studio如何直接安装release包?