1

我剛剛將數據庫從SQLite更改爲SQLCipher。我的應用程序變得令人難以置信的緩慢。它需要很長的時間來採取點擊行動。 我研究,發現這些可能有兩個原因:Android應用程序停止響應SQLCipher

  • 不要反覆打開和關閉連接,密鑰推導是非常昂貴的,由設計。頻繁地打開/關閉數據庫連接(例如,對於每個查詢)是性能問題的一個常見原因,通常可以使用單例數據庫連接輕鬆解決。

  • 使用事務來包裝插入/更新/刪除操作。除非在事務處理範圍內執行,否則每個操作都會發生在它自己的事務中,這會使事情減慢幾個數量級。

關於第一點,有人可以解釋一下,反覆打開和關閉連接意味着什麼。我想我使用SQLiteDatabase db = this.getWritableDatabase("secure_key);爲每個查詢是問題。任何關於如何使用單例數據庫連接類的例子都是非常有幫助的。

關於第二點,如何使用包裝器提供的查詢,它會有用嗎?

回答

0

關於點1)DBHelper內的以下代碼創建了單例連接(注意,我只關閉主活動的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,setTransactionSuccessfullendTransaction僅應用一次。

後續是迎合了嵌套的例子: -

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); 

     } 
    } 
} 

以上可以單獨調用,但如果要刪除一個店,然後它可以被多次調用,在這種情況下,將帶*號被稱爲*事務**是真實的(所以beginTransaction,setTransactionSuccessfulendTransaction將被跳過,並由父母完成)。

至於實用性,如果一起執行多個操作,則只能使用事務。