2013-01-16 76 views
1

我們有一個奇怪的錯誤。如果電池電量耗盡,我們的應用程序將丟失數據(存儲在SQLite中),但如果我們強行關閉應用程序然後電池電量耗盡,我們的應用程序將無法使用。電池耗盡時丟失數據

我們不確定是什麼原因造成的。

編輯1:

它意味着什麼鬆散數據?

  1. 當用戶註冊我們保存他的用戶名等
  2. 當應用程序被關閉,強制關閉,在用戶打開應用程序再次的用戶名是有
  3. 當電池耗盡和應用程序在前臺運行。電池充電並且用戶再次打開該應用程序後,用戶名不見了。

如何存儲對象:


public Void perform(SQLiteDatabase db) { 
       final ConfigEntry entry = new ConfigEntry(property, value); 

       if(contains(property)) { 
        db.update(ConfigEntry.TABLE_NAME, databaseAdapter.convertToContentValues(entry), ConfigEntry.COLUMN_NAME + " = ?", new String[] { property }); 
       } else { 
        db.insertOrThrow(ConfigEntry.TABLE_NAME, null, databaseAdapter.convertToContentValues(entry)); 
       } 
       return null; 
      } 
     }); 

所以基本上db.insertOrThrow被調用。

這是我們如何初始化數據庫:


public S doInTransaction(TransactionTask task) { 
     DatabaseHelper mDbHelper = DatabaseHelper.getInstance(mContext); 
     SQLiteDatabase mDb = mDbHelper.getWritableDatabase(); 
     mDb.setLockingEnabled(true); 
     mDb.beginTransaction(); 
     try { 
      S result = task.perform(mDb); 
      mDb.setTransactionSuccessful(); 
      return result; 
     } finally { 
      mDb.endTransaction(); 
     } 
    } 

+0

請考慮解釋*精確*你的意思是「鬆散它的數據」。 – CommonsWare

+0

即使我們不確定您的意思是「應用程序會丟失數據」是什麼意思? – AAnkit

+0

這是在傳輸中插入數據嗎?如果是,你需要提交轉換。 – wtsang02

回答

0

非常感謝所有的幫助,我們終於找到了答案。

我們正在使用用戶密碼加密我們的數據庫,並使用設備的的MAC地址提供密碼。

發生什麼事情是,有時當用戶在啓動後用完電池,當我們的應用程序運行,並且我們請求MAC地址失敗時,因爲網卡仍然被禁用或者什麼。在那種情況下,我們創建了一個新的鹽,當試圖讀取數據庫時會失敗。

1

問題是你正在使用beginTransaction()。如果你有打電話beginTransaction()你需要調用:

db.setTransactionSuccessful(); 
    } finally { 
    db.endTransaction(); 
    } 

低於或數據將不會被保存。原因是在這裏sqlite manual

而你的數據沒有保存的原因是,如果你開始交易,並且db.setTransactionSuccessful();由於系統試圖關閉它而未被調用,那麼數據將不會被保存。但是finally{}仍可能會被調用,但這並不會改變db.setTransactionSuccessful();未被調用的事實。

+0

如果我們設置了TransactionSuccessful和db.endTransaction,爲什麼不能保存呢?我不明白我們該怎麼做。 – daniel

+0

我想你的意思是,如果你沒有這個電話,你的數據將不會被保存?現在它讀取,就好像你有你的數據不會被保存的代碼。我不知道誰低估了。 – daniel

+0

@丹尼爾我的壞。 – wtsang02

1

我不知道,但我希望我能提供一些問題或啓發深入挖掘:

  1. 有,如果你的數據庫經過完整的初始創建過程中,你監控或者是表有,但只有用戶名缺失?你能否從設備上下載數據庫文件,並在PC上的SQLite工具中檢查內容?

  2. 你打開裏面doInTransaction()數據庫,但您不關閉它還有:

    public S doInTransaction(TransactionTask task) { 
        DatabaseHelper mDbHelper = DatabaseHelper.getInstance(mContext); 
        SQLiteDatabase mDb = mDbHelper.getWritableDatabase(); 
        //mDb.setLockingEnabled(true); // true is default, so it can be removed 
        mDb.beginTransaction(); 
        S result = null; 
        try { 
         result = task.perform(mDb); 
         mDb.setTransactionSuccessful(); 
        } finally { 
         // rolls back if setTransactionSuccessful() wasn't called 
         mDb.endTransaction(); 
         mDb.close(); 
        } 
        return result; 
    } 
    
  3. 你完全確定你使用相同的數據庫?我問,因爲我曾經看到有人使用時間戳作爲數據庫名稱的一部分。

  4. 您是不是錯誤地創建了一個in-memory database

  5. 設備死於低電量有多種不同的方式:它可能會死機,或者設法實際緊急停機。哪一個是這種情況?你有沒有任何日誌記錄可以提供一些內部的應用程序時,它會發生什麼?

總結:我懷疑原因是在你提供的代碼中,正如你所提到的,代碼只有在按下按鈕時纔會執行。這留下了上述問題以供進一步調查(當然,有些我可能錯過了...)。