我正在将我的资产文件夹中的数据库文件复制到安装时的数据库文件夹中。我有一个名为 firstRun 的共享首选项,默认值为 true。如果这是真的,那么我复制数据库文件并将 firstRun 值设置为假。在此过程之后,我立即在数据库表中查询一些数据。在较旧的 Android 版本 (2.1) 上,会发生 SQLite 异常(没有这样的表)并且应用程序崩溃,在 Android 4.2.1 上,dbHelper 会记录相同的消息,但会继续运行并从它未能找到的表中返回值。使用较早的 Android 版本,如果我再次启动该应用程序,则会找到数据库表,并且所有操作都会正常进行。应用程序崩溃后,我可以检查复制的数据库以及表和行是否存在。这似乎与其他真正不存在表的问题不同,因为我可以看到它们确实存在。我想知道这是否是某种同步问题,在复制过程之后表不立即存在,但在进程完成后的某个时刻存在。据我所知,这不是异步完成的,所以我不确定为什么。
这是一些显示问题的代码:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean firstRun = prefs.getBoolean(getString(R.string.first_time_run), true);
if (firstRun) {
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean(getString(R.string.first_time_run), Boolean.FALSE);
edit.commit();
try {
dbHelper.createDatabase();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// This method will fire an exception the first time the app is run - no such table
Bundle metaData = dbHelper.fetchAppMetaData();
this.appTitle = metaData.getString("app_title");
this.normalId = Integer.parseInt(metaData.getString("normal_id"));
fetchAppMetaData 方法是一个基本的 sqlite.query:
Bundle metaData = new Bundle();
Cursor dbCursor = null;
SQLiteDatabase database = getReadableDatabase();
String[] cols = new String[] {"app_title", "normal_id"};
dbCursor = database.query(true, TBL_METADATA, cols, null, null, null, null, null, null);
if (dbCursor != null) {
dbCursor.moveToFirst();
最终会返回一个包。
数据库创建方法为:
//Open the local db as the input stream
InputStream dbFromAssets = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
// Check that the directory now exists
File f = new File(DB_PATH);
if (!f.exists()) {
f.mkdir();
}
// Open the empty db as the output stream
OutputStream appDatabase = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = dbFromAssets.read(buffer)) > 0){
appDatabase.write(buffer, 0, length);
}
// Close the streams - don't cross them!
appDatabase.flush();
appDatabase.close();
dbFromAssets.close();
如有任何想法,将不胜感激。