Android SQLite 更新无法在 AsyncTask 的后台运行

Posted

技术标签:

【中文标题】Android SQLite 更新无法在 AsyncTask 的后台运行【英文标题】:Android SQLite Update not working in background in AsyncTask 【发布时间】:2017-06-01 21:25:04 【问题描述】:

我有一个有趣的问题。我有一个 SQLite 更新,我在 android 上的 AsyncTask 中执行(因为在进行 DB 调用之前我还必须进行大量远程调用)。代码就像一个魅力,除非应用程序被推到后台(例如,使用主页按钮)。该任务继续在后台成功运行,进行了 DB 调用并返回 1 行更改,但数据从未真正进入 DB。没有错误或异常。更奇怪的是,日志显示一切正常 - 没有例外,nada。 同样,当不被推到后台时,这工作正常。

电话:

    result = (sqlDB.update("FormInstance", values, "InstanceId=?",  new String[]  String.valueOf(form.getSubmissionId()) ) > 0);

此外,此调用不涉及任何事务(除非它发生在 Android SQLite 代码的底层)。

有人知道为什么会这样吗?将数据库连接或 SQLLite 推送到后台时是否发生了我不知道的事情?

更新

我尝试用 begintransaction/endtrans 包装 DB 调用,但没有成功:

    sqlDB.beginTransaction();
    try 
        result = (sqlDB.update("FormInstance", values, "InstanceId=?",  new String[]  String.valueOf(form.getSubmissionId()) ) > 0);
    
    finally 
        sqlDB.endTransaction();
    

仍然表现得好像成功但数据从未提交。请注意,我从设备中提取了数据库并验证它尚未更新。

【问题讨论】:

听起来您的事务在查询结束时没有提交。您是否尝试过自己编译查询并在事务块之间进行? @droidpl Sry- 不涉及交易。 每次您在数据库中执行某项操作时都会创建一个事务,尽管更新调用在幕后进行。你能用隐式事务来调试正在发生的事情吗? @droidpl 你的意思是围绕这个更新写一个明确的 begintran/commit 吗?我可以...有趣的是,除非将应用程序推到后台,否则它可以正常工作。我试图在调试器中遍历,但它最终挂起。 @StephenMcCormick,你怎么知道“数据从未真正进入数据库”?我怀疑如果SQLiteDatabase#update() 返回的值大于 0,那么数据确实进入了 DB,而实际错误在“观察”逻辑中。 【参考方案1】:

经过大量测试,我发现虽然有一个 onPause 方法偶尔会更新数据,但真正的问题是执行更新时 SQLLite 更新并没有真正更新一列(FormStatus)。只有在后台运行时才会出现这种情况。我通过在更新后立即查询结果来验证这一点。最终的解决方案是仅更新 FormStatus 列的辅助更新,它确实有效。用 begintrans/endtrans 包装没有帮助。

【讨论】:

以上是关于Android SQLite 更新无法在 AsyncTask 的后台运行的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法提取-Javascript Asyn问题

Android SQLite:更新语句

Android中的SQLite如何更新特定行

在 android 中将 SQLite 数据从平板电脑更新到手机

Android SQLite 更新行不起作用并且没有显示错误

SQLite 更新后:无法在 DLL 'SQLite.Interop.dll' 中找到名为 'sqlite3_changes_interop' 的入口点