android sqlite读写,用于在Android中写入SQLite数据库的推荐设计模式

伙计们,

我正在寻找一种设计模式,使UI线程能够与客户端sqlite数据库交互,该数据库可能具有批量插入(需要10秒),快速插入和读取,并且不会阻止UI线程.

我想知道我是否正在使用最佳设计模式,因为我最近调试了死锁和同步问题,而且我对我的最终产品没有100%的信心.

现在,所有数据库访问都通过单例类进行瓶颈.这是伪代码,显示我如何在我的单例DataManager中接近写入:

public class DataManager {

private sqliteDatabase mDb;

private ArrayList mCachedMessages;

public ArrayList readMessages() {

return mCachedMessages;

}

public void writeMessage(Message m) {

new WriteMessageAsyncTask().execute(m);

}

protected synchronized void dbWriteMessage(Message m) {

this.mDb.replace(MESSAGE_TABLE_NAME,null,m.toContentValues());

}

protected ArrayList dbReadMessages() {

// sqlite query for messages

}

private class WriteMessageAsyncTask extends AsyncTask> {

protected Void doInBackground(Message... args) {

DataManager.this.mDb.execsql("BEGIN TRANSACTION;");

DataManager.this.dbWriteMessage(args[0]);

// More possibly expensive DB writes

DataManager.this.mDb.execsql("COMMIT TRANSACTION;");

ArrayList newMessages = DataManager.this.dbReadMessages();

return newMessages;

}

protected void onPostExecute(ArrayList newMessages) {

DataManager.this.mCachedMessages = newMessages;

}

}

}

强调:

>首先:所有公共写操作(writeMessage)都是通过AsyncTask发生的,而不是主要的

线

>下一步:所有写操作都被同步并包装

开始交易

>下一步:读操作是

非同步,因为它们在写入期间不需要阻塞

>最后:读取操作的结果缓存在main上

onPostExecute中的线程

这是否代表了将大量数据写入sqlite数据库的Android最佳实践,同时最大限度地减少了对UI线程的影响?您在上面看到的伪代码是否存在明显的同步问题?

更新

上面的代码中存在一个重要的错误,如下所示:

DataManager.this.mDb.execsql("BEGIN TRANSACTION;");

DataManager.this.dbWriteMessage(args[0]);

该行实际上修改了数据库.此时,锁是一个RESERVED锁,因此没有其他客户端可以写.

请注意,在第一次dbWriteMessage调用之后,可能会有更多昂贵的数据库写入.假设每个写操作都发生在受保护的同步方法中.这意味着在DataManager上获取锁定,发生写入,并释放锁定.如果WriteAsyncMessageTask是唯一的编写器,这很好.

现在让我们假设还有一些其他任务也执行写操作,但不使用事务(因为它是一个快速写入).这是它的样子:

private class WriteSingleMessageAsyncTask extends AsyncTask {

protected Message doInBackground(Message... args) {

DataManager.this.dbWriteMessage(args[0]);

return args[0];

}

protected void onPostExecute(Message newMessages) {

if (DataManager.this.mCachedMessages != null)

DataManager.this.mCachedMessages.add(newMessages);

}

}

在这种情况下,如果WriteSingleMessageAsyncTask与WriteMessageAsyncTask同时执行,并且WriteMessageAsyncTask已经执行了至少一次写入,则WriteSingleMessageAsyncTask可以调用dbWriteMessage,获取对DataManager的锁定,但随后被阻止完成其写入,因为保留锁. WriteMessageAsyncTask正在重复获取并放弃对DataManager的锁定,这是一个问题.

结论:组合事务和单例对象级锁定可能导致死锁.确保在开始事务之前有对象级锁定.

我原来的WriteMessageAsyncTask类的修复:

synchronized(DataManager.this) {

DataManager.this.mDb.execsql("BEGIN TRANSACTION;");

DataManager.this.dbWriteMessage(args[0]);

// More possibly expensive DB writes

DataManager.this.mDb.execsql("COMMIT TRANSACTION;");

}

更新2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值