2013-02-13 1 views
0

Я пишу ContentProvider, которая использует SqlOpenHelper для получения своей базы данных. Я только что внес существенные изменения в базу данных, поэтому я поставил версию базы данных на одну.SqlOpenHelper # onUpgrade (...) завершается с ошибкой, когда база данных открывается как читаемая

Это случилось:

02-13 15:36:15.668: E/AndroidRuntime(15917): FATAL EXCEPTION: AsyncTask #3 
02-13 15:36:15.668: E/AndroidRuntime(15917): java.lang.RuntimeException: An error occured while executing doInBackground() 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.os.AsyncTask$3.done(AsyncTask.java:278) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.lang.Thread.run(Thread.java:864) 
02-13 15:36:15.668: E/AndroidRuntime(15917): Caused by: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 2 to 3: /data/data/com.company.anothercompany.anotherothercompany/databases/twocompanies 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:262) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at com.somo.vertu.provider.FerrariVertuContentProvider.query(FerrariVertuContentProvider.java:94) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.ContentProvider$Transport.query(ContentProvider.java:189) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.ContentResolver.query(ContentResolver.java:315) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:56) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:42) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:255) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:66) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:55) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at android.os.AsyncTask$2.call(AsyncTask.java:264) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
02-13 15:36:15.668: E/AndroidRuntime(15917):  ... 4 more 

Я зову getReadableDatabase() из функции query(...), потому что я читаю, не пишу. В этом случае onUpgrade() означает, что ничего не возвращается, но я обрабатываю это. Как я могу инициировать обновление в записываемой базе данных без вызова getWritableDatabase(...) в методе ContentProvider#onCreate()? Или это лучшее, что нужно сделать?

+0

Вопрос: используете ли вы тот же экземпляр 'SqlOpenHelper' ... вы должны хранить экземпляр' SqlOpenHelper' как поле в 'ContentProvider', а затем использовать его ... в' onUpgrade' вы должны использовать 'SQLiteDatabase', предоставленный первым параметром в этой функции ... – Selvin

ответ

1

Rewrite

У вас есть три варианта, которые я вижу:

  1. Самый простой подход, чтобы просто позвонить getWritableDatabase().
  2. Вы также можете сохранить последнюю версию базы данных (возможно, в файле SharedPreference). Затем проверьте, нужно ли обновлять базу данных внутри getReadableDatabase(), если это так непросто позвонить getWritableDatabase().
  3. Это наиболее привлекательный подход. Это требует создания собственной версии SQLiteOpenHelper, которая открывает перезаписываемую версию при возникновении обновления ...
+0

Интересная идея, хотя мне тогда пришлось бы передать эту информацию в ContentProvider , Я думаю, что что-то подобное может работать. Я подумаю об этом и дам вам знать! –

+0

На самом деле я могу переопределить 'getReadableDatabase()' для возврата 'getWritableDatabase()', если помощник определяет обновление? Я понятия не имею, как бы это сделать в 'getReadableDatabase()'. –

+0

Невозможно напрямую связать ваш SQLOpenHelper с одним или несколькими ContentProviders, подключенными к нему. Раньше я просто вызывал 'getReadableDatabase()' каждый раз, когда запрашивался ContentProvider. Таким образом, когда я загрузил резервную базу данных в фоновом режиме, ContentProvider не остался с недопустимой базой данных. – Sam