Android sqlite avec le multi thread
Je suis en train d'écrire une application android à l'aide de sqlite
. Il existe de nombreuses activités et un service. J'utilise la DB de plus d'un thread. Il fonctionne parfaitement dans Android 2.X
, mais une fois que je le lance dans Android 3.X
il jette toujours cette erreur et 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)
Quelqu'un sait pourquoi cela arrive et comment le résoudre?
J'ai fait des recherches dans internet et la plupart des gens conseillent:
- Utiliser une connexion DB, uniquement pour l'application. Comment s'assurer? Je veux partager la connexion DB pour les deux du Service et des Activités. Devrais-je le faire par créer un public statique de la variable DB?
- ContentProvider - je suis en utilisant compliqué Instruction SQL dans le code (par Exemple en joignant quelques tables, une table temporaire). Est-il possible d'exécuter ces compliquée instruction SQL dans ContentProvider?
Merci à vous tous. Enfin, (1) fonctionne très bien pour moi. Mais je me demande encore pourquoi Android 2.X n'a pas ce problème.
1) ne fonctionne que si tous les accès se produit dans le même processus, 2) fonctionne tant que vous n'avez besoin que d'insertion/de requête/mise à jour/supprimer, mais de requêtes complexes moche depuis que vous êtes limité à la developer.android.com/reference/android/content/... interface
Grâce zapl, le DB n'est pas partagée avec d'autres applications. Je pense que (1) est bon pour moi. Avez-vous une idée de pourquoi Android 2.X n'ont pas ce problème?
vous devez vous rendre sur ce lien stackoverflow.com/questions/7930139/android-databse-locked
Non 🙁
Grâce Anand, j'ai fermé la base de données et le Curseur après l'avoir utilisé. Mais l'erreur persiste
Grâce zapl, le DB n'est pas partagée avec d'autres applications. Je pense que (1) est bon pour moi. Avez-vous une idée de pourquoi Android 2.X n'ont pas ce problème?
vous devez vous rendre sur ce lien stackoverflow.com/questions/7930139/android-databse-locked
Non 🙁
Grâce Anand, j'ai fermé la base de données et le Curseur après l'avoir utilisé. Mais l'erreur persiste
OriginalL'auteur mobile app Beginner | 2012-05-04
Vous devez vous connecter pour publier un commentaire.
Numéro 1 est la réponse. J'ai plusieurs de la pile des réponses et des messages de blog sur comment exactement pour ce faire:
Quelles sont les meilleures pratiques pour SQLite sous Android?
http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection
Numéro 2 est beaucoup de travail supplémentaire et inutile. ContentProvider existe de sorte que vous pouvez partager des données avec d'autres applications. Il est utilisé pour gérer les connexions de base de données parce que les gens ne comprennent pas comment Sqlite Android et travailler ensemble.
ORMLite est sympa, mais vraiment pas nécessaire pour les accès de base de données à partir de plusieurs threads. Juste avoir une statique SQLiteOpenHelper exemple, ou de conserver une instance dans l'instance d'une Application. Vous n'aurez jamais verrouillé db questions si vous avez seulement un exemple.
Merci Kevin, ORMLite est génial de toute façon
OriginalL'auteur Kevin Galligan
Je vous suggère d'utiliser un
ContentProvider
avec unLoaderManager
chaque fois que vous le pouvez. Il est capable d'effectuer des requêtes automatiquement en arrière-plan.Je connais beaucoup de gens qui préfèrent ContentProvider, mais il est totalement pas nécessaire pour le multi-thread db accès. Si vous êtes seulement en utilisant pour cela, il n'est pas nécessaire. Toutefois, si vous aimez le ContentProvider, l'utiliser. Semble juste comme un travail supplémentaire pour moi, si.
OriginalL'auteur Adrian Monk