当我使用SQLiteAssetHelper升级已发布的数据库时,我在各种设备上收到间歇性崩溃报告。当数据库尚未完成从assets / databases文件夹到设备文件系统的传输时,似乎会发生这种情况。我已经进行了一些检查以检查升级是否已完成,但仍然存在问题。
首先,我检查以确保数据库存在。这解决了在安装应用程序时初始加载数据库的任何问题,但对更新没有帮助:
public boolean databaseLoaded(Context context) {
File dbFile = context.getDatabasePath(MyConstants.DEFAULT_DATABASE);
return dbFile.exists();
}
这是我的DatabaseHelper:
class DatabaseHelper extends SQLiteAssetHelper {
public DatabaseHelper(Context context, String databaseName, int databaseVersion) {
super(context, databaseName, null, databaseVersion);
if (databaseVersion>1 && databaseName.equals(MyConstants.DEFAULT_DATABASE)) {
setForcedUpgradeVersion(databaseVersion);
}
}
}
在我的内容提供商中,我用这种方式调用数据库:
@Override
public boolean onCreate() {
DATABASE = constants.getDBName();
db=new DatabaseHelper(getContext(), DATABASE, MyConstants.DATABASE_VERSION);
return((db == null) ? false : true);
}
在我的内容提供程序查询中,如果数据库版本(我的常量 - 不是从数据库本身检索到的)高于存储的数据库版本,我首先做一些hacky事情给它一些时间。然后它偶尔会在db.getReadableDatabase()崩溃。
@Override
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sort) {
/**if updating the app, pause to wait for the database to transfer**/
SharedPreferences sharedPreferences = getContext().getSharedPreferences(MyConstants.PREFS, 0);
int lastDBVersion = sharedPreferences.getInt("db_version", MyConstants.STARTING_DB_VERSION);
if (lastDBVersion<MyConstants.DATABASE_VERSION) {
try {
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("db_version", MyConstants.DATABASE_VERSION);
editor.commit();
}
SQLiteQueryBuilder qb=new SQLiteQueryBuilder();
qb.setTables(TABLE);
String orderBy;
if (TextUtils.isEmpty(sort)) {
orderBy=_ID;
}
else {
orderBy=sort;
}
Cursor c= null;
if (db.getReadableDatabase()!=null) {
c= qb.query(db.getReadableDatabase(), projection, selection,
selectionArgs, null, null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), url);
}
return c;
}
查看SQLiteAssetHelper库,问题是SQLiteDatabase getWritableDatabase() db.getVersion()
返回null。
我在这里缺少什么?如何检查新数据库的传输是否完整?
这是我的stacktrace:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NullPointerException
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getWritableDatabase(SQLiteAssetHelper.java:180) //this is where db.getVersion() is null
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:257)
at com.mypackage.Provider.query(Provider.java:84) //this is if (db.getReadableDatabase()!=null) {...
at android.content.ContentProvider.query(ContentProvider.java:857)
at android.content.ContentProvider$Transport.query(ContentProvider.java:200)
at android.content.ContentResolver.query(ContentResolver.java:477)
at android.content.ContentResolver.query(ContentResolver.java:420)
at com.mypackage.MyClass$MyMethod.doInBackground(MyClass.java:594) //This is Cursor c = getActivity().getContentResolver().query...
at com.mypackage.MyClass$MyMethod.doInBackground(MyClass.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more
java.lang.NullPointerException
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getWritableDatabase(SQLiteAssetHelper.java:180)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:257)
at com.mypackage.Provider.query(Provider.java:84)
at android.content.ContentProvider.query(ContentProvider.java:857)
at android.content.ContentProvider$Transport.query(ContentProvider.java:200)
at android.content.ContentResolver.query(ContentResolver.java:477)
at android.content.ContentResolver.query(ContentResolver.java:420)
at com.mypackage.MyClass$MyMethod.doInBackground(MyClass.java:594)
at com.mypackage.MyClass$MyMethod.doInBackground(MyClass.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)