Arg! Je viens de découvrir avec horreur que SQLLiteOpenHelper n’était pas thread-safe.
Plus précisément, lorsque l’on fait un ContentProvider, on a envie d’écrire quelque chose comme:
[code]
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
final String groupBy = null;
final String having = null;
switch (sUriMatcher.match(uri)) {
case URI_MATCH_1:
return db.query(TABLE1, projection,
selection, selectionArgs, groupBy, having, sortOrder);
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
}
[/code]
Hé bien, cela peut lever une exception
10-11 21:17:24.624: E/AndroidRuntime(29832): Caused by: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
En fait, la base qu’on manipule est fermée d’office lorsque
- un autre thread appelle
getWritableDatabase().
- un autre thread appelle
close() sur une autre instance de database, obtenue par un autre SQLLiteOpenHelper
Conclusion:
- Réutiliser le même
SQLLiteOpenHelper
- N’utiliser que
getWritableDatabase()
Plus de détails dans un article en anglais Database pitfalls.