【问题标题】:Setting initial values for SQLite in onCreate() of SQLiteOpenHelper在 SQLiteOpenHelper 的 onCreate() 中设置 SQLite 的初始值
【发布时间】:2014-10-04 18:27:48
【问题描述】:

我正在创建一个 Android 应用,我需要为其创建一个 SQLite DB 并使用一些值预填充它。

Android 文档说明了在 SQLiteOpenHelper 的“onCreate”中要做什么:

第一次创建数据库时调用。这就是表的创建和表的初始填充应该发生的地方。

参考 - http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onCreate(android.database.sqlite.SQLiteDatabase)

我对以下两件事持怀疑态度-

  • “第一次创建数据库时”是什么意思?这是在第一次启动应用程序时完成还是仅在第一个数据库请求(读/写等)完成时完成。

    如果是后者,我担心创建数据库可能需要相当长的时间,用值预先填充它(我有大约 60 行要插入到 1 个表中),然后读取数据库以显示它。这是最佳做法吗?

  • 我一直在 AsyncTasks 中进行所有数据库操作。但我正在使用“db.execSQL”语句在 onCreate 中创建表。这很好(就约定/性能而言)还是我也应该在这里进行 AsyncTask ?

感谢任何帮助。

【问题讨论】:

  • “第一次创建数据库时”是什么意思?这是在第一次启动应用程序时完成还是仅在第一次数据库请求(读/写等)完成时完成。 " -- 当你在SQLiteOpenHelper 上调用getReadableDatabase()getWriteableDatabase() 并且数据库文件不存在时。
  • 好的.. 但在这种情况下,这不会影响性能吗?或者,我应该使用预填充的数据库发布应用程序吗?这似乎是一项相当棘手的任务,我想我想避免它。
  • "不会影响性能吗?" -- 好吧,您必须有时打开数据库。 “或者,我应该使用预填充的数据库发布应用程序吗?”——哦,如果这是您的用例的一个选项,我肯定会这样做,using SQLiteAssetHelper。“这似乎是一项相当棘手的任务,我我想避免它”——这并不难,恕我直言。
  • 谢谢!将尝试 SQLiteAssetHelper

标签: android performance sqlite sqliteopenhelper


【解决方案1】:

1) 后者。它在第一次读取或写入 DB 时完成。

您的担心可能是正确的,这就是为什么您可以使用已经填充的数据库来发布您的应用程序。或者,您可以使用简单的 SELECT 1 FROM anytable 查询启动 AsyncTask。更多关于使用 DB here 发货的信息。 (60 行没什么好担心的,你可以放心地继续使用 AsyncTasks)。

2) 是的,没关系。 onCreate 逻辑将在您第一次读/写数据库时运行,因此如果您始终使用 AsyncTasks onCreate 也将在 AsyncTask 中运行。

【讨论】:

    【解决方案2】:

    “第一次创建数据库时”是什么意思?这是在第一次启动应用程序时完成还是仅在第一个数据库请求(读/写等)完成时完成。

    • 一般来说,当您第一次从数据库查询时会发生这种情况。之后,当您更改数据库版本时,也只会调用 Upgrade 方法。

    如果是后者,我担心创建数据库可能需要相当长的时间,用值预先填充它(我有大约 60 行要插入到 1 个表中),然后读取数据库以显示它。这是最佳做法吗?

    • 60 行插入不是一项大任务。您可以阅读更多关于插入的 beginTransaction()、commitTransaction 和 endTransaction。这将使您的插入任务快速点亮。

    我一直在 AsyncTasks 中进行所有数据库操作。但我正在使用“db.execSQL”语句在 onCreate 中创建表。这很好(就约定/性能而言)还是我也应该在这里进行 AsyncTask ?

    • 很好,您在 AsyncTask 中执行 Db 操作并且完全没问题。

    【讨论】:

    • 是的,我在 try-finally 括号中使用 beginTransaction()、setTransactionSuccessful() 和 endTransaction() 进行 DB 的初始填充。与 AsyncTask(使用游标等)相比,这在性能方面如何?
    • 感谢“beginTransaction...”提示...显着提高了速度!
    【解决方案3】:

    说到数据库操作:

    AsyncTask 中执行数据库操作通常不是一个好方法。因为你可能会遇到一个叫做“内存泄漏”的问题,它可能会在夜间作为一个无声的刺客来。

    关于这个问题有很多文章。只需谷歌“异步任务泄漏上下文”就可以了。

    那么如何进行DB操作呢?

    Loader APIContentProvider 结合使用被认为是查询数据库的好方法Loader 异步查询您的数据库并将结果传递给指定的订阅者。配置更改或其他突然的事情不会打扰它。

    一旦您知道如何使用加载器 API 来查询您的数据,真的很方便

    单次插入/更新/删除可以通过ContentResolver 直接从主线程完成。这些调用将是阻塞的(同步的),但我敢打赌,当数据量不大时,您的用户永远不会注意到任何事情。

    如果您正在处理大型数据集,并且担心会严重阻塞 UI 线程,我建议您使用 IntentService 或任何能够在后台执行操作的自定义服务(注意默认Service在主UI线程上运行,你必须自己指定后台​​操作或使用IntentService

    说到数据库初始化

    如果您要初始化大量数据,则可以创建一次性IntentService。它将异步处理您的请求,例如,执行应用程序已设置并准备就绪的广播,因此您可能会停止 “等一下,执行应用程序初始化” 屏幕并向用户显示您的数据.

    将您的数据库与应用程序一起提供也没有什么问题,尽管这似乎是一个有点骇人听闻的解决方案。

    无论哪种方式,您都可以选择更适合您的方式。

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 2011-06-28
      • 2014-11-25
      相关资源
      最近更新 更多