2013-05-17 2 views
1

В моем приложении у меня есть 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) 
+0

Если вы используете один и тот же объект/экземпляр SQLiteDatabase, весь доступ синхронизируется. Следовательно, если вы используете один и тот же объект/экземпляр SQLiteOpenHelper, весь доступ синхронизируется. Конфликтные проблемы возникают при использовании более одного экземпляра или, может быть, нескольких процессов. – CommonsWare

+0

Я использую только один экземпляр. В onCreate() в моем ContentProvider я создаю экземпляр SQLiteOpenHelper, и я использую его во всех методах моего провайдера для получения базы данных. Может быть, проблема в том, что в некоторых методах я использую getWritableDatabase() и в некоторой getReadableDatabase(), и как-то есть гонка. –

+0

Не думайте, что у вас проблема параллелизма. В случае второй ошибки более вероятно, что на устройстве заканчивается дисковое пространство (для 778). Не уверен, что первая ошибка. У вас есть трассировка стека? Какой метод вызывает это? Оператор 'INSERT', вызов' getWritableDatabase() ', что-то еще? –

ответ

0

Просто используйте один Helper внутри кода провайдера контента. Поэтому всегда подключайте 1 хелпер к 1 базе данных, и у вас не будет проблем.

В качестве альтернативы, если вы не предоставляете доступ к другим приложениям, нет необходимости использовать контент-провайдера.

Я использую контент-провайдеров в течение длительного времени, прежде чем я решил переключиться на ORMLite. И до сих пор он работал отлично во всех моих проектах. Возможно, проверьте это.

+0

Я использую только одного помощника в своем контент-провайдере. И мне нравится работать с поставщиком контента, потому что я получаю много преимуществ от его использования, и ребята из Android рекомендуют его, и все приложения Google используют его. –

+0

Да, это прекрасно по моим стандартам :) – DArkO

+0

Вы проверили учебник «Блокнот». Я использовал код таким образом, и у меня никогда не было проблем с параллелизмом. – DArkO

Смежные вопросы