android - 内容提供者和内容观察者同步

标签 android database android-contentprovider synchronized contentobserver

我有一个正在运行的服务,其中包含一个 SQLite 数据库和一个注册到数据库 URI 的内容观察器。 Content Observer 使用 SQLiteOpenHelper 从数据库查询数据。因此,当新数据通过内容提供程序从其他应用程序放入服务数据库时,将观察更改的光标并查询要处理的数据。问题是,如果我从其他应用程序快速插入数据,我最终会同时打开数据库,并导致 SQLite 错误和数据库锁定。

我正在使用 getReadable 和 getWritable 方法并在使用后关闭数据库和任何游标。看起来 CP 和 CO 不同步。我该如何解决这个问题?

更新
当我在摩托罗拉 Atrix 上测试时,我没有任何问题。当我在三星 Galaxy Tab 上测试时,我遇到了问题。在 Atrix 上,从我在目录中的调试标签看来,CO 和 CP 同时打开了数据库......但仍然没有像 Galaxy 那样的问题。 Galaxy 给了我这个错误:

11-04 12:12:13.490: ERROR/SqliteDatabaseCpp(19978): sqlite3_open_v2("/data/data/my.package/databases/raw_data_buffer.db", &handle, 6, NULL) failed
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978): Failed to open the database. closing it.
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978): android.database.sqlite.SQLiteDatabaseLockedException: database is locked
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:750)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at my.package.RawDataBufferDatabaseHelper.insert(RawDataBufferDatabaseHelper.java:93)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at my.package.NetService$NetworkPollingRunnable.run(NetService.java:166)
11-04 12:12:13.490: ERROR/SQLiteDatabase(19978):     at java.lang.Thread.run(Thread.java:1020)
11-04 12:12:13.490: WARN/dalvikvm(19978): threadid=9: thread exiting with uncaught exception (group=0x40189760)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978): FATAL EXCEPTION: Thread-14
11-04 12:12:13.490: ERROR/AndroidRuntime(19978): android.database.sqlite.SQLiteDatabaseLockedException: database is locked
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:750)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
11-04 12:12:13.490: ERROR/AndroidRuntime(19978):     at my.package.RawDataBufferDatabaseHelper.insert(RawDataBufferDatabaseHelper.java:93)

最佳答案

在这种情况下,关闭游标实际上对任何事情都没有任何影响。不要让您的 CO 直接访问数据库。让你的每一段代码都通过 ContentProvider 并且在你的内容提供者中只有一个可写和一个可读的连接打开(使这些实例变量)。这应该使所有内容保持一致,因为那样您将只有一个正在经历的数据库连接。只要您使用相同的数据库连接就可以了。 sqlite 方法是可重入的。

关于android - 内容提供者和内容观察者同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8013158/

相关文章:

当我杀死我的应用程序时,Java android 服务没有被破坏

android - addToBackStack 不适用于 onBackPressed 方法

java - 迁移到 AndroidX 后,应用程序崩溃并尝试在空引用上调用 androidx.fragment.app.FragmentManagerImpl.isDestroyed()

android - 在没有 GSM 的新华为设备中禁用 Google Play 服务警告

c - main() 在信号处理期间是否暂停?

android - 当为给定的 URI 调用 ContentResolver.notifyChange() 时,是否会通知观察该 URI 的后代 URI 的 ContentObservers?

sql - 向新创建的用户授予权限的 DDL 触发器

mysql - 从表中获取字段 x 的值最大的行

android - 从 JSON 文件在 xml 布局中设置文本

android - 从自定义键盘复制/粘贴剪贴板