无法从SQLiteOpenHelper中的资产/复制数据库



我有一个预先填充的DB,我已经离线创建并放入assets/目录中。当调用SQLiteOpenHelper.onCreate()时,我正试图复制它,但遇到了严重的问题。

public void onCreate(SQLiteDatabase db) {
importAssets();
}

当我这样写代码时,在随后尝试从数据库中获取数据时,我总是会出现无此类表错误。我做了一些处理,开始将SQL语句插入onCreate()以及对importAssets()的调用,例如:

public void onCreate(SQLiteDatabase db) {
importAssets();
db.execSQL("CREATE TABLE main_table (some_col);");
}

现在,当我运行该应用程序时,我遇到了一个列未找到错误(上面的架构与DB访问代码所期望的不匹配,它缺少了许多列。在该应用程序的第二次运行中,android_metatdata被损坏,然后一切都见鬼去了。我还在importAssets()调用之前尝试过SQL代码,结果同样糟糕。

所以我开始认为,我在importAssets()中进行的文件复制本质上被onCreate()截断了。我说得对吗?直接使用SQL在onCreate()中创建数据库的唯一方法是什么?我可以不使用此函数从assets/复制现成的数据库吗?

我已通过使用Log()调用确认importAssets()运行正常。以下是完整的功能:

private void importAssets() throws IOException
{  
AssetManager am = mCtx.getAssets();
InputStream in = am.open(DB_NAME);
FileOutputStream out;
byte[] buffer = new byte[1024];
int len;
File db;
db = new File(DB_DIR + "/" + DB_NAME);
// copy the DB from assets to standard DB dir created above
out = new FileOutputStream(db);
while ((len = in.read(buffer)) > 0)
{
out.write(buffer, 0, len);
}
out.flush();
out.close();
in.close();
if (!db.exists())
{
Log.e(TAG, DB_DIR + "/" + DB_NAME + " does not exist");
}
}

我在其他地方看到了在SQLiteOpenHelper构造函数中复制文件的建议,但这意味着我必须手动检查importAssets()中文件的存在,因为每次使用DB时都会调用构造函数。此外,onCreate()对于我想做的事情实际上是无用的,尽管我看不出有任何方法可以避免。

我现在确信我的怀疑是对的。SQLiteOpenHelperonCreate()函数将创建DB文件,该文件在对超类构造函数的调用的name参数中指定。然后,它希望您使用各种DB库从onCreate()函数中修改这个DB文件(添加表、数据、更改表等)从其他地方复制文件只会被截断

我不知道它是如何或为什么这样做的,但这使得onCreate()无法通过从assets/完整复制数据库来"创建"数据库,这正是我所需要的。我已经将importAssets()移到构造函数中,并添加了适当的检查,以便在它已经存在的情况下不覆盖它。onCreate()中没有任何内容,这似乎不会干扰其他地方正在发生的事情。

我认为SQLiteOpenHelper确实需要运行SQLite脚本的能力。这样,当我真正想做的只是设置DB时,我就不必在Java代码中硬编码SQL的长块。

相关内容

  • 没有找到相关文章

最新更新