(原创)android Sqlite多线程访问异常解决方案
在开发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;
}
上面提供一个使用方法,现在项目中使用这种方法关于数据库的操作从未没有出现并发的问题,大家可以尝试一下。
(原创)android Sqlite多线程访问异常解决方案的更多相关文章
- CoreData和SQLite多线程访问时的线程安全
关于CoreData和SQLite多线程访问时的线程安全问题 数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常 ...
- SQLite多线程写锁文件解决方案
在sqlite编程中多线程同时写时会出现异常,我写了个类来解决这个问题. 思路很简单,就是在开始写操作时,记下写操作的托管线程id,表示目前有线程正在做写操作:其他线程来写时,需要先检测是否有进程正在 ...
- 关于CoreData和SQLite多线程访问时的线程安全问题
数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常用的两种数据持久化存储方式:CoreData和SQLite,两 ...
- CoreData和SQLite多线程访问时的线程安全问题
数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常用的两种数据持久化存储方式:CoreData和SQLite,两 ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- 多线程访问winform控件出现异常的解决方法
一. 多线程访问winform控件出现异常的解决方法 1. 问题描述<1> 如果创建某控件的线程之外的其他线程试图调用该控件,则会引发一个 InvalidOperationExcept ...
- IOS 使用FMDB多线程访问数据库 及databaseislocked的问题
原理:文件数据库sqlite,同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写.在操行写操作时,数据库文件被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,能过重新编译s ...
- Android实现网络访问
Android实现网络访问 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 1) 熟练使用HttpURLConnection访问WebServ ...
- [转] c#中 多线程访问winform控件
原文 c#中多线程访问winform控件的若干问题小结 我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来解决这个问题,下面我将详细的 ...
随机推荐
- Vectoroid
Use cases Drawing (sketch, illustrations, cartooning, etc). Diagramming (any sort of chart with obje ...
- 一款 .NET 下的轻量级 REST 和 HTTP API 客户端 - RestSharp
项目地址:https://github.com/restsharp/RestSharp Features Supports .NET 3.5+, Silverlight 4, Windows Phon ...
- 听声辨位识DUMP
要处理的dump成千上万,每个都用眼睛去看也太累了,不如用耳朵听好了.相信经过一段时间适应,一定可以做到凭听就解决dump分析.(逃 DumpMusican 这个小exe只需要把dump路径作为参数传 ...
- teamcity设置
建立项目后首先要设置svn地址,并绑定 名字随便起 url是svn的地址 之后来做build step 有一个按钮可以自动检测,一般都能检测出来 执行这个似乎需要代理装什么东西 可以查看目前代理有那些 ...
- 队列的图文解析 和 对应3种语言的实现(C/C++/Java)
概要 本章和介绍"栈"时的流程一样,先对队列进行介绍,然后分别给出队列的C.C++和Java三种语言的实现.内容包括:1. 队列的介绍2. 队列的C实现3. 队列的C++实现4. ...
- 基于HTML5技术的电力3D监控应用(四)
回答了知乎问题较长,一些使用WebGL的经验,作为新的一篇: 正好逛到这个问题,正好是2013年底,正好最近基于的HT for Web 3D做的电力项目收尾,正好用到的就是WebGL技术,因此说说自己 ...
- SQL SERVER 分布式事务(DTC)
BEGIN DISTRIBUTED TRANSACTION指定一个由 Microsoft 分布式事务处理协调器 (MS DTC) 管理的 Transact-SQL 分布式事务的起始. 语法BEGIN ...
- UINavigationItem和UItabBarItem的区别详解
一.UINavigationItem 1> 获得方式 self.navigationItem // self是指控制器 2> 作用 可以用来设置当前控制器顶部导航栏的内容 // 设置导航栏 ...
- IOS开发UI基础UITextView相关属性
UITextView相关属性 • text: 设置textView中文本_textView.text = @"Now is the time for all good develope ...
- Sprint总结和第八九十的读书笔记
总结:经过这次的Sprint,我在从中收获了很多.作为产品负责人的我,主要责任就是合理分配任务给自己的队友,调动队友的积极性.虽然这其中也有些不尽人意的地方,但是我们都坚持的走了过来,团队合作真的很重 ...