Reputation: 8543
Quite frequently I get the following exception and I'm really entirely sure what to do about it.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: android.database.sqlite.SQLiteException: error code 5: database is locked
at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61)
at android.database.sqlite.SQLiteDatabase.delete(SQLiteDatabase.java:1704)
at azurewing.android.db.provider.NotificationProvider.delete(NotificationProvider.java:80)
at azurewing.android.db.provider.Provider.delete(Provider.java:87)
at azurewing.android.db.provider.NotificationProvider.delete(NotificationProvider.java:1)
at android.content.ContentProvider$Transport.delete(ContentProvider.java:234)
at android.content.ContentResolver.delete(ContentResolver.java:692)
at azurewing.android.db.table.NotificationTable.removeAllNotifications(NotificationTable.java:89)
at azurewing.android.sync.SyncReceiver$1$1.doInBackground(SyncReceiver.java:52)
at azurewing.android.sync.SyncReceiver$1$1.doInBackground(SyncReceiver.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
... 4 more
I am accessing a ContentProvider (NotificationProvider here) via an AsyncTask. The ContentProvider uses a database of course.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
SQLiteDatabase db = database.getWritableDatabase();
int numDeleted = database.delete(NotificationTable.TABLE_NAME, selection, selectionArgs);
return numDeleted;
}
I'm a bit stumped about what to do here. It's clearly a threading issue I think, so I'm thinking of everytime I get the database, I do it from a synchronized method in 1 class. Is this a good idea?
Upvotes: 1
Views: 6694
Reputation: 1007359
Either:
Consolidate those to be one provider with one SQLiteOpenHelper
, comparing the Uri
values to see which set of logic to go through, or
Create four separate databases, one per provider/SQLiteOpenHelper
, or
Have a singleton SQLiteOpenHelper
that all four providers share
SQLite threading in Android is managed by SQLiteDatabase
. You need exactly one instance of a SQLiteDatabase
that all threads share for this to work. If you are using SQLiteOpenHelper
, this usually means that you use exactly one instance of SQLiteOpenHelper
, since it wraps the SQLiteDatabase
.
Upvotes: 6