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

发布于 2024-12-13 11:55:27 字数 3574 浏览 5 评论 0原文

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

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

更新 当我在摩托罗拉 Atrix 上测试时,没有任何问题。当我在 Samsung Galaxy Tab 上测试它时,我遇到了问题。在 Atrix 上,从目录中的调试标签看来,CO 和 CP 同时打开了 DB...但仍然不像 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)

I have a service running that contains an SQLite DB and a Content Observer registered to the DB's URI. The Content Observer uses an SQLiteOpenHelper to query the data from the DB. So when new data is put into the services DB from other application via Content Provider the changed cursor will be observed and query the data to process. The problem is if I insert data at a fast pace from other applications I end up with both the Content Observer and Content Provider opening the DB and causes an SQLite error with a database lock.

I am using the getReadable and getWritable methods and closing the DB and any cursors after they are used. It just seem that the CP and CO are not in sync. How can I fix this problem?

UPDATE
When I test this on a Motorola Atrix I have no problems. When I test it on a Samsung Galaxy Tab I get problems. On the Atrix it appears from my debug tags in the catlog that both the CO and the CP have the DB open at the same time... but still not problem like there is with the Galaxy. The Galaxy gives me this error:

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)

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

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

发布评论

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

评论(1

神回复 2024-12-20 11:55:27

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

Closing the cursors really doesn't have any affect on anything in this case. Don't have your CO's directly accessing the database. Make every piece of your code go through the ContentProvider and in your content provider only have one writeable and one readable connection open (make these instance variables). That should keep everything consistent because then you'll only have one db connection that you're going through. As long as you're using the same db connection you're fine. The sqlite methods are reentrant.

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