【问题标题】:Update local Android database更新本地 Android 数据库
【发布时间】:2014-09-22 07:50:37
【问题描述】:

我目前遇到了 Android 上的 SQLite 数据库问题。

我的应用程序有一个本地数据库,位于 apk 文件中。当应用程序启动时,它将检查新版本,如果可用,则下载全新的数据库(尽管在两个数据库版本之间,变化很小)。但是现在数据库太大了。因此,新数据库可用需要很长时间。那么这个问题有什么解决办法吗?

【问题讨论】:

  • 使用 AsyncTask,您可以在后台进行大型操作并恢复进度以将其显示给客户或在任务完成时显示通知。 developer.android.com/reference/android/os/AsyncTask.html
  • 实现一个 API 考虑上次同步的时间并且只下载更新的/新的值?如果onUpgrade中存在drop table,不需要drop table,直接调用api问一下?
  • 是的,我在想什么,但 mac os 或 java lib 上的任何工具都支持它吗?
  • 客户端应用程序是否曾经对本地数据库进行过更改(除了从服务器下载新版本时)?

标签: android database sqlite


【解决方案1】:

不是获取一个全新的数据库文件,而是获取更改。更改可能采用 SQL 脚本的形式。让服务器为每次更新生成更改脚本,然后您可以下载SQL脚本并在本地数据库上依次运行。

【讨论】:

  • 是的,我在想什么,但 mac os 或 java lib 上的任何工具都支持它吗?
  • 你不需要任何库。您需要做的就是修改 SQL 查询以仅获取更改。
  • 请更具体:(
【解决方案2】:

你的问题不清楚的是如果你想要

  1. 双向同步(客户端和服务器可以进行数据更改)或仅
  2. 单向同步(只有服务器或客户端可以进行更改)。

对我来说,这听起来更像是您想要从服务器到客户端的单向同步。这正是 Google I/O 对会议数据所做的事情。您可以在此处找到详细的博客条目:
Conference Data Sync and GCM in the Google I/O App,只需查看处理manifest.jsonsessions.jsonspeakers.json 的“有效下载会议数据”一章。如果数据架构发生变化,只需提供一个新应用程序,它以标准的 android 方式执行架构更改,并使您的 json 解析例程以忽略其他字段的方式进行。就像加法一样:

如果您想要双向同步,那么chiastic-security 为数据库操作提供了一个很好的概述。缺少的是解决方案的编程部分:

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    基本思路

    这就是我的做法。我在这里假设客户端应用程序不会更改本地数据库(除非它下载新版本),因此只有几个可能的数据库版本存在(每次你有一个在服务器端进行了更改)。

    1. 为每个名为LastModified 的表添加一列,默认值为NOW()。这意味着每次您向主副本添加内容时,它都会获得更新的LastModified 设置。您必须确保您的更新(而不是插入)也更改了 LastModified 字段。
    2. 在数据库中的某处(Settings 表或其他东西)存储一个字段,用于跟踪此版本数据库在服务器上发布的日期(称为 PublishDate)。
    3. 当客户端想要检查新版本时,它会将其PublishDate 发送到服务器。然后服务器检查每个表,并找到LastModifiedPublishDate 之后的每一行。它向客户端发送 SQL 以在客户端上插入或更新这些行。它还会发送新的PublishDate,以便客户端可以在其本地副本中更新它。

    这涉及插入和更新。它不处理删除。在您的情况下,它们可能不是问题;如果是:

    1. 添加一个单独的表来记录删除,您还可以在其中跟踪LastModified,以便您可以告诉客户端要删除哪些行;或者最好有一个设置,您实际上不会删除任何行,而只是将它们更新为标记为“已删除”。

    最后,这不会处理架构更改。同样,希望这不是您的问题:希望您有一个稳定的架构。但是,如果您确实需要添加或删除表或索引或其他内容,则必须单独完成:

    1. 在您的主服务器上创建一个SchemaChanges 表,每当您进行结构更改时,将相关详细信息连同LastModified 日期一起放入SchemaChanges 表中,以便您可以根据要求将其发送给客户也。如果您这样做,您需要先将架构更改发送到客户端,因为它们可能会影响其他更改的含义。

    现在这样做的好处是您可以预处理服务器上的所有内容(因为只有几个版本存在)。对于每个旧版本,您可以计算将旧版本升级到新版本的更改(基于上述详细信息),然后将生成的 SQL 存储在服务器上。如果这样做,您就无需即时生成 SQL:当客户端发送 PublishDate 时,您只需查找已经计算的 SQL,它将版本从 PublishDate 转换为最新版本.

    替代实现

    有一种很好且简单的方法来推动上述方案为您提供的更改,即使是不需要LastModified 次的轻微简化,或者实际上对您现有的结构进行任何更改。在服务器端,您已经拥有旧版本(因为您拥有所有旧版本)和新版本,您创建两个数据库的 SQL 转储,然后在它们上运行 diff 以生成您需要的补丁文件可以发送到客户端应用程序。客户端应用程序将使用相同的 Java 库生成旧版本的 SQL 转储,然后将diff 补丁应用到它以创建新版本的完整 SQL 转储。此时,它可以删除旧数据库并从 SQL 转储中创建新数据库。

    如果更改不是整体更改,这将非常有效(在这种情况下,您最好只推送新的.db 文件)。

    invoking the SQLite binary 很容易做到这一点来创建转储。您需要根据执行外部命令的this way 对 Android 的方法稍作修改。

    您可以使用this Google library在服务器端计算差异补丁并在客户端应用它们。

    【讨论】:

    • 你有什么工具可以生成从旧数据库转移到新数据库的sql文件吗?
    • @CaoManhDat 我已经添加了另一个部分来讨论这个问题,并通过使用 SQLite 转储和 Google diff 库来计算差异来简化一些事情。
    【解决方案4】:

    您需要为您对服务器上的数据库所做的任何更改创建一个时间戳。

    当应用连接到您的服务器时,它会发送上次下载的时间戳,以便您的服务器知道要下载的新数据是什么。

    设备上的时间戳不是基于实时设置的,您也需要下载它以避免时区问题是不同的小时值。

    如果您愿意,可以使用连续数字版本来代替时间戳

    【讨论】:

      【解决方案5】:

      我一直在处理类似的问题,每次服务器发生任何更改时,我都必须更新本地数据库。诀窍是跟踪 android 本地数据库中的最后更新时间,并发送该时间以仅以 JSON 格式从服务器获取更新。在这里,您必须编写服务器端代码,将输入作为最后更新时间,并以 JSON 格式返回对服务器端数据库所做的所有更新。

      获取JSON数据后,你必须将JSON数据转换为SQL查询,并在本地数据库中插入或更新。

      看看this的回答。另请查看 Google IO 2014 代码here

      我最终将 ContentProvider 与架构和合同类一起使用,如 here 所述。

      然后,我为数据库中的每个表创建了 java 对象,并使用 gson library 将传入的 JSON 更新转换为 java 对象。之后,您必须按照documentation 中的说明编写插入/更新/删除查询。

      所以基本上,您必须为数据库处理创建合同、数据库和提供者类。并且为数据库中的每个表创建一个 java 类,并且您编写了用于从服务器获取 JSON 更新的代码,将 JSON 字符串转换为 java 对象,然后在数据库中插入/更新/删除。 Google IO 2014 应用中提供了演示代码。

      【讨论】:

        【解决方案6】:

        使用 greenDao 你可以执行这样的迁移,Check 在这里。祝你好运。

        【讨论】:

          【解决方案7】:

          您可以通过 Google Cloud Messaging API 执行此操作。这是 Google 为开发人员提供的一项功能,适用于 Android 和 IOS 设备。 Google Cloud Messaging (GCM) 是一项服务,可帮助开发人员在在线服务器和应用程序之间发送数据。使用此服务,您可以在新数据可用时向您的应用程序发送数据,而不是及时向服务器发出新请求。

          使用 GCM 的一个很好的教程是 this

          希望对你有帮助:)

          【讨论】:

            【解决方案8】:

            也许您可以使用服务来更改数据库版本。因此用户无法注意到这一点,并且用户继续使用该应用程序。服务完成后,应用程序会发送通知。当然只有方法和建议。

            【讨论】:

              猜你喜欢
              • 2020-05-05
              • 2011-11-13
              • 1970-01-01
              • 1970-01-01
              • 2011-10-17
              • 1970-01-01
              • 2020-04-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多