В моем приложении у меня есть SyncAdapter
, который использует ContentProvider
для размещения данных в SQLiteDatabase. Все отлично работало месяцами. После того, как я добавил второй способ обновить ContentProvider от уведомлений GCM кнопочных, я начинаю получать отчеты об ошибках от некоторых пользователей, какСинхронизировать доступ к поставщику контента
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 3850)
ИЛИ
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 778)
и несколько других исключений, связанных с SQLite.
Хотя я слышал, что Sqlite синхронизирован, и нам не нужно беспокоиться, я получаю эти ошибки, указывающие, что мне нужно как-то синхронизировать. Кто-нибудь имел дело с этой проблемой?
EDIT: Вот пример StackTrace
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 778)
1
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
2
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:906)
3
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
4
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
5
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
6
at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1365)
7
at com.makanstudios.conscious.provider.ConsciousProvider.doInsert(ConsciousProvider.java:225)
8
at com.kaciula.utils.provider.BasicContentProvider.insert(BasicContentProvider.java:80)
9
at android.content.ContentProvider$Transport.insert(ContentProvider.java:201)
10
at android.content.ContentResolver.insert(ContentResolver.java:866)
11
at com.makanstudios.conscious.net.DatabaseHandler.updateStatsCount(DatabaseHandler.java:351)
12
at com.makanstudios.conscious.net.DatabaseHandler.updateStatsCount(DatabaseHandler.java:362)
13
at com.makanstudios.conscious.gcm.GCMIntentService.onMessage(GCMIntentService.java:124)
14
at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:223)
15
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
16
at android.os.Handler.dispatchMessage(Handler.java:99)
17
at android.os.Looper.loop(Looper.java:137)
18
at android.os.HandlerThread.run(HandlerThread.java:60)
И еще один пример StackTrace:
0
android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.
1
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
2
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:318)
3
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:229)
4
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:515)
5
at android.database.sqlite.SQLiteConnectionPool.reconfigure(SQLiteConnectionPool.java:339)
6
at android.database.sqlite.SQLiteDatabase.reopenReadWrite(SQLiteDatabase.java:832)
7
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:213)
8
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
9
at com.kaciula.utils.provider.BasicContentProvider.insert(BasicContentProvider.java:76)
10
at android.content.ContentProvider$Transport.insert(ContentProvider.java:201)
11
at android.content.ContentResolver.insert(ContentResolver.java:869)
12
at com.makanstudios.conscious.net.DatabaseHandler.updateStatsCount(DatabaseHandler.java:351)
13
at com.makanstudios.conscious.net.DatabaseHandler.updateStatsCount(DatabaseHandler.java:362)
14
at com.makanstudios.conscious.gcm.GCMIntentService.onMessage(GCMIntentService.java:124)
15
at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:223)
16
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
17
at android.os.Handler.dispatchMessage(Handler.java:99)
18
at android.os.Looper.loop(Looper.java:137)
19
at android.os.HandlerThread.run(HandlerThread.java:60)
Если вы используете один и тот же объект/экземпляр SQLiteDatabase, весь доступ синхронизируется. Следовательно, если вы используете один и тот же объект/экземпляр SQLiteOpenHelper, весь доступ синхронизируется. Конфликтные проблемы возникают при использовании более одного экземпляра или, может быть, нескольких процессов. – CommonsWare
Я использую только один экземпляр. В onCreate() в моем ContentProvider я создаю экземпляр SQLiteOpenHelper, и я использую его во всех методах моего провайдера для получения базы данных. Может быть, проблема в том, что в некоторых методах я использую getWritableDatabase() и в некоторой getReadableDatabase(), и как-то есть гонка. –
Не думайте, что у вас проблема параллелизма. В случае второй ошибки более вероятно, что на устройстве заканчивается дисковое пространство (для 778). Не уверен, что первая ошибка. У вас есть трассировка стека? Какой метод вызывает это? Оператор 'INSERT', вызов' getWritableDatabase() ', что-то еще? –