Android 应用停止响应 SQLCipher
Android App stops responding for SQLCipher
我刚刚将我的数据库从 SQLite 更改为 SQLCipher。我的应用程序变得非常慢。采取点击操作需要很长时间。
我研究了一下,发现了这两个可能的原因:
不要重复打开和关闭连接,因为密钥推导的成本非常高,这是设计使然。频繁打开/关闭数据库连接(例如对于每个查询)是性能问题的一个非常常见的原因,通常可以使用单例数据库连接轻松解决。
使用事务来包装插入/更新/删除操作。除非在事务范围内执行,否则每个操作都将发生在它自己的事务中,这会减慢几个数量级。
关于第一点,请大神解释一下反复打开和关闭连接是什么意思。我认为我对每个查询都使用 SQLiteDatabase db = this.getWritableDatabase("secure_key);
是问题所在。任何有关如何为此使用单例数据库连接 class 的示例都会有很大帮助。
关于第二点,我如何为提到的查询使用包装器,它会有用吗?
关于第 1 点,以下代码在 DBHelper
中创建了一个单例连接(注意我只在 Main Activity 的 onDestroy
方法中关闭了数据库).
/**
* Instantiates a new Db helper.
*
* @param context the context
*/
DBHelper(Context context) {
super(context, DBConstants.DATABASE_NAME, null, 1);
}
private static DBHelper instance;
/**
* Gets helper.
*
* @param context the context
* @return the helper
*/
static synchronized DBHelper getHelper(Context context) {
if(instance == null) {
instance = new DBHelper(context);
}
return instance;
}
并且您使用以下方法来获取您的助手:-
dbhelper = DBHelper.getHelper(context);
db = dbhelper.getWritableDatabase();
关于您使用的 2,db.beginTransaction();
开始事务,db.setTransactionSuccessful();
在进行数据库更改后将其标记为成功(这是必需的,以便要应用的事务。否则,结束事务将有效地否定应用的任何更改) 和db.endTransaction();
以完成事务。
请注意,事务不会嵌套,因此在嵌套事务时,您必须添加代码,以便 beginTransaction
、setTransactionSuccessfull
和 endTransaction
仅应用一次。
下面是一个适合嵌套的例子:-
void deleteAisle(long aisleid, boolean intransaction) {
if (doesAisleExist(aisleid)) {
if (!intransaction) {
db.beginTransaction();
}
String whereargs[] = {Long.toString(aisleid)};
// Delete ProductUsage rows that have Aisle as a parent
pudeletes = db.delete(
DBProductusageTableConstants.PRODUCTUSAGE_TABLE,
DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL +
" = ?",
whereargs
);
// More done here but removed for brevity (including deletion of the Aisle)
if (!intransaction) {
db.setTransactionSuccessful();
db.endTransaction();
msg = "DB Transacion SET and ENDED for Aisle ID=" + Long.toString(aisleid);
}
}
}
以上可以单独调用,但如果删除商店,则可以多次调用,在这种情况下,它会在 **intransaction ** 为真时被调用(所以 beginTransaction
, setTransactionSuccessful
和 endTransaction
将被跳过并留给父级完成)。
至于有用性,只有在同时执行多项操作时才会使用事务。
我刚刚将我的数据库从 SQLite 更改为 SQLCipher。我的应用程序变得非常慢。采取点击操作需要很长时间。 我研究了一下,发现了这两个可能的原因:
不要重复打开和关闭连接,因为密钥推导的成本非常高,这是设计使然。频繁打开/关闭数据库连接(例如对于每个查询)是性能问题的一个非常常见的原因,通常可以使用单例数据库连接轻松解决。
使用事务来包装插入/更新/删除操作。除非在事务范围内执行,否则每个操作都将发生在它自己的事务中,这会减慢几个数量级。
关于第一点,请大神解释一下反复打开和关闭连接是什么意思。我认为我对每个查询都使用 SQLiteDatabase db = this.getWritableDatabase("secure_key);
是问题所在。任何有关如何为此使用单例数据库连接 class 的示例都会有很大帮助。
关于第二点,我如何为提到的查询使用包装器,它会有用吗?
关于第 1 点,以下代码在 DBHelper
中创建了一个单例连接(注意我只在 Main Activity 的 onDestroy
方法中关闭了数据库).
/**
* Instantiates a new Db helper.
*
* @param context the context
*/
DBHelper(Context context) {
super(context, DBConstants.DATABASE_NAME, null, 1);
}
private static DBHelper instance;
/**
* Gets helper.
*
* @param context the context
* @return the helper
*/
static synchronized DBHelper getHelper(Context context) {
if(instance == null) {
instance = new DBHelper(context);
}
return instance;
}
并且您使用以下方法来获取您的助手:-
dbhelper = DBHelper.getHelper(context);
db = dbhelper.getWritableDatabase();
关于您使用的 2,db.beginTransaction();
开始事务,db.setTransactionSuccessful();
在进行数据库更改后将其标记为成功(这是必需的,以便要应用的事务。否则,结束事务将有效地否定应用的任何更改) 和db.endTransaction();
以完成事务。
请注意,事务不会嵌套,因此在嵌套事务时,您必须添加代码,以便 beginTransaction
、setTransactionSuccessfull
和 endTransaction
仅应用一次。
下面是一个适合嵌套的例子:-
void deleteAisle(long aisleid, boolean intransaction) {
if (doesAisleExist(aisleid)) {
if (!intransaction) {
db.beginTransaction();
}
String whereargs[] = {Long.toString(aisleid)};
// Delete ProductUsage rows that have Aisle as a parent
pudeletes = db.delete(
DBProductusageTableConstants.PRODUCTUSAGE_TABLE,
DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL +
" = ?",
whereargs
);
// More done here but removed for brevity (including deletion of the Aisle)
if (!intransaction) {
db.setTransactionSuccessful();
db.endTransaction();
msg = "DB Transacion SET and ENDED for Aisle ID=" + Long.toString(aisleid);
}
}
}
以上可以单独调用,但如果删除商店,则可以多次调用,在这种情况下,它会在 **intransaction ** 为真时被调用(所以 beginTransaction
, setTransactionSuccessful
和 endTransaction
将被跳过并留给父级完成)。
至于有用性,只有在同时执行多项操作时才会使用事务。