SQLiteException:错误代码5:数据库已锁定。从AsyncTask访问ContentProvider时

时间:2013-09-07 13:50:10

标签: android

我经常遇到以下异常,我完全相信该怎么办。

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

我通过AsyncTask访问ContentProvider(此处为NotificationProvider)。 ContentProvider当然使用数据库。

@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;
}

我有点难过这里要做什么。这显然是我认为的一个线程问题,所以我想每次得到数据库时,我都是从1类的同步方法中做到的。这是个好主意吗?

1 个答案:

答案 0 :(得分:6)

或者:

  • 将那些作为一个提供商合并为一个SQLiteOpenHelper,比较Uri值以查看要经历的逻辑集,或者

  • 创建四个单独的数据库,每个提供商一个/ SQLiteOpenHelper

  • 拥有所有四个提供商共享的单身SQLiteOpenHelper

Android中的SQLite线程由SQLiteDatabase管理。您只需要一个SQLiteDatabase的实例,所有线程都共享这个实例。如果您使用SQLiteOpenHelper,这通常意味着您只使用SQLiteOpenHelper的一个实例,因为它包装了SQLiteDatabase