问题场景描述:

在页面中用到了ViewPager控件,ViewPager中的内容分别是两个ListView,两个ListView的数据都来自本地数据库(先从网络下载数据,然后更新本地数据库),在实际的使用过程中发现会出现SQLiteDatabaseLockedException: database is locked的问题。

经网上搜索资料,发现是读写数据库时存在的同步问题,所以采用单例+同步锁的方法,并且在每次数据库操作后都关闭数据库,经测试后发现没有在出现上述问题。

以下是两个主类

DBHelper.java(这个类用来管理数据库)

public class DBHelper extends SQLiteOpenHelper {

	private final String TAG = this.getClass().getSimpleName();

	public final static String DATABASE_NAME = "test.db";
public final static String TABLE = "table";
public final static int DATABASE_VERSION = 2; public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
} private static DBHelper mInstance; public synchronized static DBHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DBHelper(context);
}
return mInstance;
}; @Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE
+ "(id INTEGER PRIMARY KEY ,data BLOB)");
} catch (SQLiteException e) {
e.printStackTrace();
}
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 删除原来的数据表
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
// 重新创建
onCreate(db);
} public static byte[] objectToBytes(Object obj) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream sOut = new ObjectOutputStream(out);
sOut.writeObject(obj);
sOut.flush();
byte[] bytes = out.toByteArray();
return bytes;
} public static Object bytesToObject(byte[] bytes) throws Exception { ByteArrayInputStream in = new ByteArrayInputStream(bytes);
ObjectInputStream sIn = new ObjectInputStream(in);
return sIn.readObject();
}
}

  DBStudentManager类(这里可以定义自己的管理类)

public class DBStudentManager {

	private DBHelper helper;
private SQLiteDatabase db; public DBStudentManager(Context context) {
helper = DBHelper.getInstance(context);
db = helper.getWritableDatabase();
} // 插入
private void insert(Student student) { synchronized (helper) {
// 看数据库是否关闭
if (!db.isOpen()) {
db = helper.getWritableDatabase();
}
// 开始事务
db.beginTransaction();
try {
db.execSQL(
"INSERT INTO " + DBHelper.TABLE + " VALUES(?,?)",
new Object[] { student.mID,
DBHelper.objectToBytes(student) });
db.setTransactionSuccessful(); // 设置事务成功完成
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
} // 更新
private void update(Student student) { synchronized (helper) {
if (!db.isOpen()) {
db = helper.getWritableDatabase();
}
db.beginTransaction();
try {
db.execSQL("UPDATE " + DBHelper.TABLE
+ "SET data = ? WHERE id = ?",
new Object[] { DBHelper.objectToBytes(student),
student.mID });
db.setTransactionSuccessful(); // 设置事务成功完成
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
} // 同步
public void synchronous(List<Student> students) {
if (students == null) {
return;
}
for (Student student : students) {
if (query(student.mID) == null) {
insert(student);
} else {
update(student);
}
}
} // 删除指定数据
public void delete(String id) { synchronized (helper) {
if (!db.isOpen()) {
db = helper.getWritableDatabase();
}
db.beginTransaction();
try {
db.execSQL("DELETE FROM " + DBHelper.TABLE + " WHERE id = ? ",
new String[] { id });
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
} // 删除所有数据
public void delete() { synchronized (helper) {
if (!db.isOpen()) {
db = helper.getWritableDatabase();
}
db.beginTransaction();
try {
db.execSQL("DELETE * FROM " + DBHelper.TABLE);
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
} // 查找所有的Students
public List<Student> query() { List<Student> students = new ArrayList<Student>();
synchronized (helper) {
if (!db.isOpen()) {
db = helper.getWritableDatabase();
}
Cursor c = queryTheCursor();
Student student = null;
try {
while (c.moveToNext()) { byte[] bytes = c.getBlob((c.getColumnIndex("data")));
student = (Student) DBHelper.bytesToObject(bytes);
students.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
c.close();
}
}
return students;
} // 查找指定ID的Student
public Student query(String id) { Student student = null;
synchronized (helper) {
if (!db.isOpen()) {
helper.getWritableDatabase();
}
Cursor c = queryTheCursor(id);
try {
while (c.moveToNext()) { byte[] bytes = c.getBlob((c.getColumnIndex("data")));
student = (Student) DBHelper.bytesToObject(bytes);
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
c.close();
}
}
return student;
} // 获取游标
public Cursor queryTheCursor(String id) {
Cursor c = db.rawQuery("SELECT FROM " + DBHelper.TABLE
+ " WHERE id = ?", new String[] { id });
return c;
} // 获取游标
public Cursor queryTheCursor() {
Cursor c = db.rawQuery("SELECT * FROM " + DBHelper.TABLE);
return c;
} class Student { String mID;
String mName;
int mAge;
}
}

  

Android多线程操作sqlite(Sqlite解决database locked问题)(2)使用事务处理的效果的更多相关文章

  1. Android多线程操作sqlite(Sqlite解决database locked问题)

    参考http://blog.csdn.net/sdsxleon/article/details/18259973  很好 https://github.com/2point0/Android-Data ...

  2. Android多线程操作,as快捷键笔记

    Android studio 快捷键 cmd+p 快速查看该方法的参数定义 * * option + shift +上下 快速移动上下行 * * cmd + e 显示最近操作的文件 * * cmd + ...

  3. android 多线程

    本章讲述在android开发中,多线程的应用.多线程能够处理耗时的操作并优化程序的性能.本章主要介绍知识点,AsyncTask,Java线程池,ThreadPoolExecutor线程池类.本章案例只 ...

  4. sqlite:多线程操作数据库“database is locked”解决方法(二)

    上一篇博客<sqlite:多线程操作数据库“database is locked”解决方法>通过注册延时函数的方法来处理数据库被锁的问题.此方法固然能解决问题,但是在多个线程向数据库写入大 ...

  5. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  6. Sqlite 数据库出现database disk image is malformed报错的解决方法

    软件用的是Sqlite数据库,昨天还好好的,今天开机登录软件报错:database disk image is malformed 用Sqlite Expert Personal 重建索引,发现其中一 ...

  7. [Android] Android 使用 Greendao 操作 db sqlite(2)-- 封装DaoUtils类

    继续接上文: Android 使用 Greendao 操作 db sqlite(1)-- 直接在MainActivity中调用 布局文件同上文一致,这里就不贴了. 一.封装DaoUtils类 User ...

  8. [Android] Android 使用 Greendao 操作 db sqlite(1)-- 直接在MainActivity中调用

    继续接上文: Android 使用 Greendao 操作 db sqlite 布局文件: activity_test_green.xml <?xml version="1.0&quo ...

  9. [Android] Android 使用 Greendao 操作 db sqlite

    Android 使用 Greendao 操作 db sqlite GreenDAO是一个开源的安卓ORM框架,能够使SQLite数据库的开发再次变得有趣.它减轻开发人员处理低级数据库需求,同时节省开发 ...

随机推荐

  1. 搭建FTP服务器 window7

    1.安装IIS组件,打开控制面板-->程序和功能,点击打开或关闭windows功能 找到Internet信息服务,勾选FTP服务器和Web管理工具下的IIS管理控制台进行安装ftp,如图所示 2 ...

  2. 4.Mysql中的运算符

    4.Mysql中的运算符运算符用来连接表达式.运算符包括:算术运算符.比较运算符.逻辑运算符.位运算符. 4.1 算术运算符算术运算符包括加(+).减(-).乘(*).除(/).取模(%,MOD) 5 ...

  3. Python爬虫的原理

    简单来说互联网是由一个个站点和网络设备组成的大网,我们通过浏览器访问站点,站点把HTML.JS.CSS代码返回给浏览器,这些代码经过浏览器解析.渲染,将丰富多彩的网页呈现我们眼前: 一.爬虫是什么? ...

  4. python文件读取操作、序列化

    1.对文件进行读写操作时,先建立文件句柄 f = open("test.txt","r",encoding="UTF-8") 其中,r为文件 ...

  5. npm run build出问题十分通用的解决方法

    1.C:\NanoFabric\52ABP\SPAHost\ClientApp\node_modules 原来的目录重命名为C:\NanoFabric\52ABP\SPAHost\ClientApp\ ...

  6. redis在游戏服务器中的使用初探(三) 信息存储

    摘要: 搭建了服务器环境 有了客户端 我们来假想下以下应用场景:我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:用户ID,为查找的key,存储的value ...

  7. note:debugging requires the debug connect session system privilege

    note:debugging requires the debug connect session system privilege 解决方案: 原因是用户权限不够,使用以下命令授予权限: GRANT ...

  8. Java的GUI设计小技巧

    不可关闭窗口 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

  9. oracle创建表空间、添加数据库文件

    创建表空间: create [undo|TEMPORARY]tablespace venn datafile '/opt/oracle/db01/app/oracle/oradata/OSSORCL/ ...

  10. jmeter读取csv文件

    操作步骤: 1.读取csv文件 2.编辑httpSampler