问题描述
我写使用 sqlite的一个Android应用程序
。有很多的活动和一个服务。我使用DB从多个线程。它完美的的Android 2.X
,但一旦我在的Android 3.X
运行它,它总是抛出这个错误和强制关闭
:
05-04 22:17:04.815:I / SqliteDatabaseCpp(8774):sqlite的返回:错误code = 5,味精=数据库被锁定,DB = /数据/数据/ XXX /数据库/ IM
05-04 22:17:04.815:E / SqliteDatabaseCpp(8774):sqlite3_open_v2(/数据/数据/ XXX /数据库/ IM,&安培;手柄,6,NULL)失败
05-04 22:17:04.835:E / SQLiteDatabase(8774):无法打开数据库。关闭它。
05-04 22:17:04.835:E / SQLiteDatabase(8774):android.database.sqlite.SQLiteDatabaseLockedException:数据库已锁定
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.database.sqlite.SQLiteDatabase.dbopen(本机方法)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:790)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
05-04 22:17:04.835:E / SQLiteDatabase(8774):在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
任何人都知道它为什么会发生,以及如何解决呢?
我已经研究了互联网,大多数人提醒:
- 使用只为应用程序使用一个数据库连接。如何保证呢?我想分享两个服务和活动的数据库连接。我应该创建一个公共静态DB变量做呢?结果
- ContentProvider的 - 我正在使用code复杂的SQL语句(如加入几张桌子,临时表)。是否有可能在运行ContentProvider的这些复杂的SQL语句?
结果搜索结果
谢谢大家。最后,(1)对我来说工作正常。但我仍然不知道为什么的Android 2.X没有这个问题。
1号就是答案。我有几个堆答案,关于究竟如何做到这一点的博客文章:
What是Android上的SQLite的最佳做法?
2号是一个很多额外的工作和不必要的。 ContentProvider的存在,所以你可以与其他应用程序的数据。它用于管理数据库连接,因为人们不理解SQLite和Android的如何协同工作。
I am writing a android application using sqlite
. There are many activities and one service. I use the DB from more than one thread. It works perfectly in Android 2.X
, but once I run it in Android 3.X
it always throws this error and Force Close
:
05-04 22:17:04.815: I/SqliteDatabaseCpp(8774): sqlite returned: error code = 5, msg = database is locked, db=/data/data/xxx/databases/im
05-04 22:17:04.815: E/SqliteDatabaseCpp(8774): sqlite3_open_v2("/data/data/xxx/databases/im", &handle, 6, NULL) failed
05-04 22:17:04.835: E/SQLiteDatabase(8774): Failed to open the database. closing it.
05-04 22:17:04.835: E/SQLiteDatabase(8774): android.database.sqlite.SQLiteDatabaseLockedException: database is locked
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:790)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
05-04 22:17:04.835: E/SQLiteDatabase(8774): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
Anyone knows why it happen and how to solve it?
I have researched in the internet and most people advise:
- Use one DB connection only for the application. How to ensure it? I want to share the DB connection for both of the Service and Activities. Should I do it by create a public static DB variable?
- ContentProvider - I am using complicated SQL Statement in code (Such as joining few tables, temporary table). Is it possible to run these complicated SQL statement in ContentProvider?
Thank you everyone. Finally, (1) works fine for me. But I still wonder why Android 2.X does not have this problem.
Number 1 is the answer. I have several stack answers and blog posts about how exactly to do that:
What are the best practices for SQLite on Android?
http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection
Number 2 is a lot of extra work and unnecessary. ContentProvider exists so you can share data with other apps. Its used to manage database connections because people don't understand how Sqlite and Android work together.
这篇关于Android的sqlite的多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!