2013-01-16 79 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. 设备死于低电量有多种不同的方式:它可能会死机,或者设法实际紧急停机。哪一个是这种情况?你有没有任何日志记录可以提供一些内部的应用程序时,它会发生什么?

总结:我怀疑原因是在你提供的代码中,正如你所提到的,代码只有在按下按钮时才会执行。这留下了上述问题以供进一步调查(当然,有些我可能错过了...)。