Android ContentProvider 是否可以支持 DB 表的添加-交换-删除?

发布于 2024-10-24 11:26:05 字数 278 浏览 5 评论 0原文

我被要求提供一个双缓存方案来同步云数据库和设备数据库。要求是创建一组表,然后在某个时间点,同一组表的镜像将发生同步。完成后,ContentProvider 会在应用程序注意到的情况下将一组交换为另一组。

这可能吗?

我可以安全地添加-交换-删除表吗? 我可以安全地添加、交换、删除多个表吗?某些活动可能会显示连接?

欢迎提出意见和想法,但不能选择“合并同步”现有表。

我担心的是,在表集上操作的活动或服务中可能存在未完成的游标,并且无法确保它们在删除可能访问的表之前已关闭游标。

I am being asked to provide a dual-cache scheme for syncing cloud DB with device DB. The requirement is to create a set of tables and then at some point in time, the sync will occur to a mirror of the same set of tables. When done, the ContentProvider is expected to swap one set for the other without the application noticing.

Is this possible?

Can I add-swap-drop tables safely?
Can I add-swap-drop several tables safely - some activities may be displaying joins?

Comments and ideas are welcome, but it is not an option to "merge sync" the existing tables.

My concern is that there can be outstanding cursors in Activities or Services that are operating on the table-set and no way to assure that they have closed the cursor before the table that it may be accessing is dropped.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蝶舞 2024-10-31 11:26:05

是的,这是可能的(尽管您的客户要求的两个表听起来像是一个非常丑陋的黑客。)

您的 ContentProvider 预计会提供一个游标,以响应特定的内容 URI。如何将该 URI 映射到数据库中的表完全取决于您。

所以这样做:
使用相同的数据库架构创建 2 个表“data1”和“data2”。像平常一样用您的数据填充 data1 。当应用程序查询您的 URI 时,请使用填充有 data1 中的数据的光标进行响应。

之后,填写data2。当命令到来并且需要切换表时,使用您用于该数据的(一个)URI 调用 notifyChange()。所有正在侦听的游标(您的显示应用正在使用 RegisterContentObserver(),不是吗?)将收到您的 URI 处的数据已更改的通知。当他们收到通知时,他们会重新查询。这次,您的 ContentProvider 将使用 table2 而不是 table1 中的数据进行应答...游标不知道它是从哪个填充的,只是知道什么 URI。因此,对于使用数据的应用程序来说,更改是完全透明的(只要两个表具有相同的架构)。

我忽略了命令开关并保存哪个表处于活动状态。这显然是特定于您的应用程序,但您应该已经能够找到一种好方法来保留该信息。

至于表 JOIN...当然,技巧是确保执行 JOIN 本身的逻辑发生在 ContentProvider 内部,而不是应用程序内部。然后,您只需一次切换几组表,并从正确的组中执行 JOIN 操作。

最后,对于过时游标,游标包含表数据的副本,而不是对表本身的任何引用。因此,如果表消失,游标数据在最坏的情况下也会过时。它不会保持桌子打开等。 Cursor 保留对其来源的 Content URI(而不是表)的反向引用。因此,当它再次查询时,它会像上面一样工作。

Yes it is possible (Even though your two-table requirement from your customer sounds like a really ugly hack.)

Your ContentProvider is expected to serve up a cursor, in response to a specific Content URI. How that URI gets mapped to a table in the database is completely up to you.

So do this:
Create 2 tables, "data1" and "data2" with an identical database schema. Fill data1 with your data like normally. When an app queries your URI, respond with a cursor filled with data out of data1.

Later, fill up data2. When the command comes and it's time to switch tables, call notifyChange() with the (one) URI you use for that data. All the cursors that are listening (Your display apps are using RegisterContentObserver() aren't they?) will be notified that the data at your URI has changed. When they get that notify, they'll re-query. This time, your ContentProvider will answer with data out of table2 instead of table1... The cursor doesn't know what table it's filled from, just what URI. So to the applications using the data, the change is completely transparent (as long as the two tables have the same schema.)

I've glossed over commanding the switch and saving which table is active. That's obviously kind of application specific to you, but you should be able to find a good way to persist that information already.

As for table JOINs... The trick of course is to ensure that the logic to do the JOIN itself happens inside the ContentProvider, not inside the app. Then, you just switch several sets of tables at once, and do JOIN out of the right sets.

Finally, as for stale Cursors, the Cursor contains a copy of table data, not any reference to the table itself. So if the table goes away, the Cursor data would be stale, at worst. It won't hold the table open or the like. The Cursor keeps a back-reference to the Content URI it came from, not the table. So, again, when it requeries, it'll work just like above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文