首页 技术 正文
技术 2022年11月21日
0 收藏 379 点赞 5,166 浏览 2116 个字

在开发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 这样的类,具体代码见下面的代码块:

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();
}
}

在我们进行关闭数据库的时候判断

mOpenCounter.decrementAndGet() == 0 (更新器管理的给定对象的字段的当前值为0)的时候才正式关闭数据库,就不会出现上述异常。用方式呢,在我们操作数据库逻辑代码中如下使用
首相要取得
mDatabaseManager = DatabaseManager.getInstance(mContext);
对象
    /***
* 判断表中是否有值
*/
public boolean isExistTabValus() {
boolean flag = false;
SQLiteDatabase db = mDatabaseManager.getReadableDatabase();//获取一个可读的数据库对象
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();//关闭数据库
}
return flag;
}

上面提供一个使用方法,现在项目中使用这种方法关于数据库的操作从未没有出现并发的问题,大家可以尝试一下。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,076
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,400
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,812
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,894