Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android应用程序停止响应SQLCipher_Android_Performance_Android Sqlite_Android Database_Sqlcipher Android - Fatal编程技术网

Android应用程序停止响应SQLCipher

Android应用程序停止响应SQLCipher,android,performance,android-sqlite,android-database,sqlcipher-android,Android,Performance,Android Sqlite,Android Database,Sqlcipher Android,我刚刚将数据库从SQLite更改为SQLCipher。我的应用程序变得难以置信的慢。执行单击操作需要很多时间。 我研究并发现了这两个可能的原因: 不要重复打开和关闭连接,因为设计上密钥派生非常昂贵。频繁打开/关闭数据库连接(例如,对于每个查询)是导致性能问题的常见原因,通常可以使用单例数据库连接轻松解决。 使用事务包装插入/更新/删除操作。除非在事务范围内执行,否则每个操作都将发生在它自己的事务中,这会将速度降低几个数量级。 关于第一点,请有人解释一下反复打开和关闭连接意味着什么。我想我对每

我刚刚将数据库从SQLite更改为SQLCipher。我的应用程序变得难以置信的慢。执行单击操作需要很多时间。 我研究并发现了这两个可能的原因:

  • 不要重复打开和关闭连接,因为设计上密钥派生非常昂贵。频繁打开/关闭数据库连接(例如,对于每个查询)是导致性能问题的常见原因,通常可以使用单例数据库连接轻松解决。

  • 使用事务包装插入/更新/删除操作。除非在事务范围内执行,否则每个操作都将发生在它自己的事务中,这会将速度降低几个数量级。

关于第一点,请有人解释一下反复打开和关闭连接意味着什么。我想我对每个查询都使用
SQLiteDatabase db=this.getWritableDatabase(“secure_key);
是个问题。任何关于如何使用singleton数据库连接类的示例都会很有帮助

关于第二点,我如何使用wrapper进行上述查询,它是否有用?

关于第1点)以下代码在
DBHelper
中创建了一个单例连接(注意,我只在主活动的
onDestroy
方法中关闭数据库)

您可以使用以下方法获取帮助者:-

    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**为true的情况下调用它(因此,
BeginTranssaction
setTransactionSuccessful
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);

        }
    }
}