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

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

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


更多相关文章

  1. Android 对话框【Dialog】去除白色边框代码
  2. android操作系统默认的图片
  3. Android -很全的android操作内容丰富
  4. 介绍一下android的各种权限。 代码如下: Html代码 <manifestxmlns
  5. android UI跨线程操作
  6. android aosp 下载源代码
  7. 《android开发应用实战详解》光盘源代码
  8. android SQLite数据库存储数据

随机推荐

  1. android 联系人源码分析 新字段的添加流
  2. Android读写XML(下)――创建XML文档
  3. Android处理异步耗时任务,AsyncTask使用教
  4. Android常用组件之四大天王
  5. 由浅入深研究Android(1)--开篇•序
  6. error: Error parsing XML: unbound pref
  7. Ubuntu下安装VirtualBox和Android(安卓)
  8. Google Map Android v2开发: 安装运行Goo
  9. 关于 android 加载 res 图片 out of memo
  10. 【视频】 安卓渗透课程收集整理