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

Android SQLiteException:错误代码5:数据库已锁定。从AsyncTask访问ContentProvider时,android,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

我经常会遇到以下异常,我真的完全确定该怎么办

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
我正在通过异步任务访问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;
}
我对在这里做什么感到有点困惑。我认为这显然是一个线程问题,所以每次我得到数据库时,我都会从一个类中的同步方法中进行。这是个好主意吗?

或者:

  • 使用一个
    SQLiteOpenHelper
    将这些文件合并为一个提供程序,比较
    Uri
    值以查看要执行的逻辑集,或者

  • 创建四个独立的数据库,每个提供程序一个/
    SQLiteOpenHelper
    ,或

  • 拥有一个所有四个提供者共享的单例
    SQLiteOpenHelper

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

  • 使用一个
    SQLiteOpenHelper
    将这些文件合并为一个提供程序,比较
    Uri
    值以查看要执行的逻辑集,或者

  • 创建四个独立的数据库,每个提供程序一个/
    SQLiteOpenHelper
    ,或

  • 拥有一个所有四个提供者共享的单例
    SQLiteOpenHelper


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

您是否碰巧在清单中的某个地方使用了
android:process
。不,我在清单中的任何地方都没有。您是否使用了多个
SQLiteOpenHelper
实例?可能一个由
ContentProvider
提供,另一个在别处提供?我有一个helper抽象提供程序类,它有一个SQLiteOpenHelper实例。我有4个提供程序,这意味着该提供程序将存在多个实例。您是否碰巧在清单中的某个地方使用了
android:process
?刚刚搜索过。不,我在清单中的任何地方都没有。您是否使用了多个
SQLiteOpenHelper
实例?可能一个由
ContentProvider
提供,另一个在别处提供?我有一个helper抽象提供程序类,它有一个SQLiteOpenHelper实例。我有4个提供者,这意味着该提供者将存在多个实例。太棒了。。我相信这就是原因。一旦我把所有的代码都写好了,我会回来接受这个问题。您认为为每个提供者创建单独的数据库有什么好处吗?(我的提供者都映射到表)@Amorgos:“你认为为每个提供者创建一个单独的数据库有什么好处吗?”--我认为这是一个缺点,特别是如果你想提供任何类型的备份机制。我只是把它列为候选解决方案。我理解,但如果出于某种原因确实需要单独的SQLiteDatabase实例,它可能是一个潜在的解决方案。但是我没有。我现在已经为所有提供程序实例的SQLiteOpenHelper实例创建了一个单例。我假设SQLiteOpenHelper实例将处理SQLiteDatabase实例的单例包装?因此,现在我在所有提供程序方法中以及在多个线程(使用AsyncTask)中打开和关闭同一个db实例。你觉得现在安全吗?@Amorgos:听起来当然更好。太棒了。。我相信这就是原因。一旦我把所有的代码都写好了,我会回来接受这个问题。您认为为每个提供者创建单独的数据库有什么好处吗?(我的提供者都映射到表)@Amorgos:“你认为为每个提供者创建一个单独的数据库有什么好处吗?”--我认为这是一个缺点,特别是如果你想提供任何类型的备份机制。我只是把它列为候选解决方案。我理解,但如果出于某种原因确实需要单独的SQLiteDatabase实例,它可能是一个潜在的解决方案。但是我没有。我现在已经为所有提供程序实例的SQLiteOpenHelper实例创建了一个单例。我假设SQLiteOpenHelper实例将处理SQLiteDatabase实例的单例包装?因此,现在我在所有提供程序方法中以及在多个线程(使用AsyncTask)中打开和关闭同一个db实例。你觉得现在安全吗?@Amorgos:听起来肯定更好。