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

时间:2012-11-16 07:33:28

标签: android android-sqlite android-assets

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

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

当我编写这样的代码时,在随后尝试从数据库中获取数据时,我始终会遇到没有这样的表错误。我做了一些事情,开始在onCreate()中插入SQL语句以及调用importAssets(),例如:

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

现在,当我运行应用程序时,我遇到了列未找到错误的问题(上述架构与数据库访问代码所需的内容不匹配,它缺少许多列。应用程序的第二次运行,android_metatdata被破坏,然后一切都变成了地狱。我也在importAssets()调用之前尝试了SQL代码,结果也是类似的灾难。

所以我开始认为我在importAssets()中所做的文件副本基本上被onCreate()截断了。我对吗?是通过直接使用SQL在onCreate()中创建数据库的唯一方法吗?我是否可以不使用此功能从assets/复制现成的数据库?

我已确认importAssets()使用Log()来电正确运行。这是完整的功能:

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");
    }
}

我已经看到elsewhere建议我在SQLiteOpenHelper构造函数中执行文件复制,但这意味着我必须手动检查importAssets()中文件是否存在,因为构造函数得到了每次我使用DB时调用。此外,onCreate()对我想做的事情实际上没用,但我认为没有办法避免这种情况。

1 个答案:

答案 0 :(得分:2)

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

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

我认为onCreate()确实需要运行SQLite脚本的能力。这样我就不必将长长的SQL代码硬编码到我的Java代码中,而我真正想做的就是进行数据库设置。