Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了SQLCipher for Android getReadableDatabase()Overherad大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
修改了我的 DatabaseHelper类以使用sqlCipher库.

为此,我:

>将资产复制到我的资产文件夹和库(armeabi,x86,commons-codec,guava-r09,sqlcipher)到我的libs文件夹中.
>更改了DatabaseHelper类中的导入,以便它们指向导入net.sqlcipher.database.*.
>调用sqliteDatabase.loadLibs(getApplicationContext());当应用程序启动时.
>修改了我调用getReadableDatabase()和getWriteableDatabase()的行,以便它们包含密码作为参数;

当数据被正确读取/写入时,一切似乎都能正常工作.我的问题与性能有关,因为我的应用程序可能会以某种频率执行数据库操作,导致它变慢(在迁移到sqlCipher之后).

对于我的DatabaseHelper方法,我相信我遵循标准方法,例如:

/*
 * GetTing all MyObjects
 */
public List<MyObject> getMyObjects() {

    List<MyObject> objects = new ArrayList<MyObject>();

    String SELEctQuery = "SELECT * FROM " + TABLE_NAME;
    Log.v(LOG,SELEctQuery);

    // Open
    sqliteDatabase db = this.getReadableDatabase("...the password...");  
    // I kNow this passphrase can be figured out by decompiling.

    // cursor with query
    cursor c = db.rawQuery(SELEctQuery,null);

    // looping through all rows and adding to list
    if (c.moveToFirst()) {
        do {
            MyObject object = createMyObjectFromcursor(c); // Method that builds MyObject from cursor data
            // adding to list
            objects.add(object);
        } while (c.moveToNext());
    }

    c.close();
    db.close();
    return objects;
}

我并不完全熟悉sqlCipher的内部机制(例如,它解密整个数据库文件,当我打电话getReadableDatabase()?),但是,在调试时,似乎开销是getReadableDatabase(密码)和getWritableDatabase(密码),如果我的假设是真的,这是有道理的.

将这些调用移动到DatabaseHelper.open()和DatabaseHelper.close()方法,它们会在实例化DatabaseHelper时调用,而不是在每个单独的方法调用它们,这是一种不好的做法吗?请分享您有关如何解决此问题的知识.

编辑:

我已经使用DDMS跟踪其中一个方法,我可以看到开销实际上是在sqliteOpenHelper.getReadableDatabase()(每次大约需要4秒).查询似乎工作得很快,我认为我不需要担心它们.

如果我深入了解电话,每次跟踪持续时间最长的电话,我最终得到:

sqliteDatabase.openOrCreateDatabase – > sqliteDatabase.openDatabase – > sqliteDatabase.openDatabase – > sqliteDatabase.setLocale

所以sqliteDatabase.setLocale(java.util.LocalE)似乎是罪魁祸首,因为每次调用getReadableDatabase()需要大约4秒.我查看了sqliteDatabase的源代码,它只是锁定了DB,调用了native_setLocale(locale.toString(),mFlags)(这里发生了4秒的开销)并解锁了DB.

知道为什么会这样吗?

解决方法

您看到的性能问题很可能是由于sqlCipher密钥派生. sqlCipher打开数据库性能故意慢,使用PBKDF2执行密钥派生(即成千上万的SHA1操作)来抵御暴力破解和字典攻击(你可以在 http://sqlcipher.net/design阅读更多相关信息).此活动将推迟到第一次使用数据库时,这恰好发生在setLocale中,这就是您在分析时看到性能问题的原因.

最好的选择是缓存数据库连接,以便可以多次使用它,而无需重复打开和键入数据库.如果可以,在启动期间打开数据库一次是首选的操作过程.对同一数据库句柄的后续访问不会触发密钥派生,因此性能会快得多.

如果这不可能,则另一个选项是禁用或削弱密钥派生.这将导致sqlCipher在导出密钥时使用更少轮的PBKDF2.然这会使数据库打开得更快,但从安全角度来看,它显着变弱.因此,除特殊情况外,不建议使用.也就是说,这里有关于如何减少KDF迭代的信息:

http://sqlcipher.net/sqlcipher-api/#kdf_iter

大佬总结

以上是大佬教程为你收集整理的SQLCipher for Android getReadableDatabase()Overherad全部内容,希望文章能够帮你解决SQLCipher for Android getReadableDatabase()Overherad所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。