java - 安卓光标: database being modified as it is being read

标签 java android database bluetooth android-contentprovider

我的应用程序是一个短信应用程序,用于发送和接收短信,但有以下区别:所有消息都通过蓝牙发送到您的电脑,我的其他应用程序(C#和WPF)将在您的电脑上发送允许用户编写和接收短信。

我的应用程序未设置为默认短信应用程序,并且一直兼容至API Lv 9

当用户需要加载所有短信并将其发送到 PC 时,我使用光标从内部短信数据库读取:

final Uri uriSMSInbox = Uri.parse("content://sms/inbox");
final Uri uriSMSSent = Uri.parse("content://sms/sent");
final Cursor cursorInbox = this.context.getContentResolver()
       .query(uriSMSInbox, null, null, null, null);
final Cursor cursorSent = this.context.getContentResolver()
       .query(uriSMSSent, null, null, null, null);

我创建了一个 Message 类来表示 SMS(主要具有不可变的最终字段,用于 ID、内容、地址、时间戳)。使用 cursor.moveNext() 时,我填写了一个消息列表,它将代表所有存储的短信。

到目前为止,我可以发送和接收消息,一切正常。

但问题是,当 PC 应用程序发送消息时,它会创建一个 Message 对象,并通过蓝牙将其发送到 Android 应用程序。但我怎样才能设置它的不可变 ID 呢?它应该与内部 SMS 数据库中的数据库相匹配!

所以我每次发送消息时都会尝试查询数据库...问题是内部数据库并不总是立即更新。所以“我的”消息还不存在......! 根据最终用户设备(硬件、Android 版本等)的不同,更新所需的时间可能会有很大差异

这样我就可以自己设置ID。我可以询问数据库最后一个ID是什么,但是如果用户交换大量短信怎么办?如果收到或发送了十几条短信怎么办...我如何确定我设置的 ID 就是数据库中的 ID?

我需要同步手机和电脑之间的短信数据库,以便用户不必每次启动 Android 应用程序时都发送所有短信:他应该能够同步丢失的消息(如果他在我的应用程序之外聊天)。

还有什么比使用 ID 来快速比较和检查更好、更快的方法呢?

这是我的问题:

  1. Android(或 4.4+ 中的 SMS 默认应用程序)是否以异步方式更新内部 SMS 数据库,或者是否锁定它以防止多线程访问和(更重要的是)修改它以防止 <强>竞争条件?

  2. 使用Content Provider是否会返回一个Cursor,表示给定时刻数据库的某种“副本”,因此会忽略任何修改如果发生修改?

  3. 或者它是否锁定数据库,这意味着 Android(或默认短信应用程序)会等到我读完才更新它?

一种解决方案是设置一个计时器,定期检查 SMS 数据库并正确设置 ID。这是一个好方法吗?

最佳答案

回答您的问题:

  1. 在 4.4+ 中,Android 不执行更新,它仅创建允许应用执行更新的权限。可以想象,应用程序创建者可以编写不安全的多线程代码,就像 4.4 之前一样。这种情况并不常见,但有可能。

  2. ContentProvider 确实返回一个 Cursor,并且它可以具有观察者,如果基础数据更新,则观察者会失效并重新查询。因此,如果您愿意,您可以注册以接收这些更新的通知。假设您确实希望 ID 与数据库匹配,那么在插入数据之前您无法知道 ID - 这意味着您需要等到这种情况发生。这可能意味着某些消息的同步速度没有您想要的那么快,但它们会在某个时刻同步。

  3. 当您打开光标并正在读取数据库时,数据库不会锁定。更新可能会导致您的光标失效。一般来说,您应该注册更新Cursor,否则在读取一行之前,它可能会被删除,然后Cursor将抛出异常。

关于java - 安卓光标: database being modified as it is being read,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31166730/

相关文章:

java - 在 Comparable 接口(interface)中覆盖 compareTo() 的问题

java - 如何允许测试辅助方法抛出异常而不在调用方法中捕获异常?

android - Espresso - 单击 gridview 中的图像

database - 为什么在处理数据字段/名称时约定和一致性很重要?

数据库设计 - 仪表板

php - 外键可以为空或留空吗?

java - 如何让我安装的 Java 程序运行?

java - 如何将 jar 导入我的 java 程序?

android - 无法登录谷歌游戏服务

android - 我可以在图形布局编辑器中预览操作栏吗?