2013-02-13 80 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 

我從query(...)函數調用getReadableDatabase()因爲我讀,不寫。在這種情況下,onUpgrade()意味着什麼都沒有返回,但我正在處理。如何在不需要在ContentProvider#onCreate()方法中調用getWritableDatabase(...)的情況下觸發可寫數據庫的升級?或者這是最好的事情?

+0

問題是:你是否使用'SqlOpenHelper'的同一個實例......你應該將'SqlOpenHelper'實例存儲爲字段在ContentProvider中,然後在onUpgrade中使用它,你應該使用這個函數中的第一個參數提供的SQLiteDatabase ... – Selvin 2013-02-13 16:05:23

回答

1

重寫

你有三個選擇,我看到:

  1. 最簡單的方法是簡單地調用getWritableDatabase()
  2. 您還可以存儲最後一個數據庫版本(可能位於SharedPreference文件中)。然後檢查數據庫是否需要在getReadableDatabase()內部升級,如果是這樣,請偷偷撥打getWritableDatabase()
  3. 這是最涉及的方法。它需要創建自己的SQLiteOpenHelper版本,當升級發生時打開一個可寫版本...
+0

有意思的想法,但是我必須把這些信息傳遞給'ContentProvider' 。我認爲這樣的事情可能會起作用。我會考慮它並讓你知道! – 2013-02-13 15:59:14

+0

實際上,如果助手確定升級到期,我可以重寫'getReadableDatabase()'返回'getWritableDatabase()'嗎?但我不知道如何在'getReadableDatabase()'中選擇它。 – 2013-02-13 16:01:23

+0

您的SQLOpenHelper沒有直接的方式與連接到它的一個或多個ContentProvider進行通信。在過去,我每次查詢ContentProvider時都簡單地調用'getReadableDatabase()'。這樣,當我在後臺加載備份數據庫時,ContentProvider沒有留下無效的數據庫引用。 – Sam 2013-02-13 16:06:32