5

我在不止一个 SQLite 教程中注意到,在onCreate()扩展类的情况下会重新创建表SQLiteOpenHelper。在 Firefox 插件的帮助下,我已经在 Android 环境 (Eclipse IDE) 之外创建了我的 SQLite 数据库和表。数据库表位于预期的位置:

C:\aXX3&Space\Android\workspace\OnDemandAndAutomatic_Project\assets

对我来说,每次都必须以编程方式重新创建它们似乎很奇怪(显然,它们继续存在并保留数据,或者有什么意义)?但是,我现在对这个应用程序有一个严重的问题,这导致我提出我的问题:

  • 真的有必要每次都提醒Android关于数据库吗?

令我懊恼的是,我刚刚意识到,我没有在 中创建我的数据库表C:\aXX3&Space\Android\workspace\OnDemandAndAutomatic_Project\assets,而是将它们放入C:\aXX3&Space\Android\workspace\OnDemandAndAutomatic\assets了应用程序的早期版本,但是将 SQLite 文件复制到正确的位置并没有改变任何事情。如果这是导致问题的原因,因为我的应用程序正在寻找一个 AWOL 数据库,那么简单地复制和粘贴文件是否还不够?我必须做些什么来正式 将数据库引入system/Android/Eclipse目录吗?有什么建议么?

4

3 回答 3

5

我想你在这里误解了。当一个 SQLiteOpenHelper 对象被构造时,它会检查 SQLite 数据库是否存在,如果不存在,它会调用它的onCreate()方法(通常开发者实现创建数据库的 SQL)

更新:
@Clay Shannon:我将解释 Eclipse 和 Android 项目的工作机制。假设您使用 Eclipse 来编写 Android 项目。新项目将在工作空间中创建一个项目文件夹(在您的情况下,它是C:\aXX3&Space\Android\workspace并且项目文件夹是OnDemandAndAutomatic_Project)。这个文件夹会包含几个子文件夹如:src, bin, assets, res,... 每个文件夹都有自己的作用,你对assets文件夹感兴趣吧?Assets 文件夹用于包含参考文件(不能或您不想放在 res 文件夹中),例如:html 文件、声音文件、图像文件、文本文件......当 Eclipse 从项目构建 apk 时,这些文件也包含在 apk 中。当您在 Android 设备上安装 apk 时,会将 apk 复制到 Android 系统文件夹中,并创建一个包含应用程序数据的文件夹,如 Dharmendra 所述:/data/data/{packagename}/(包名,例如 com.google。应用程序等,并且此路径适用于您设备的 Android 操作系统,而不适用于 Windows)。

你的情况是你想使用你已经存在的数据库,所以你需要实现一个函数来检查你的数据库是否存在,如果不复制你的数据库到数据库路径/data/data/{packagename}/databases/,并在您的应用启动时调用该函数。如何做到这一点已经在这里回答了如何将现有数据库从一个应用程序复制到另一个应用程序。这里也是访问资产文件的参考,以防您不知道http://www.wiseandroid.com/post/2010/06/14/Android-Beginners-Intro-to-Resources-and-Assets.aspx

希望现在你能解决你的问题。注意:您已经存在的数据库必须是 SQLite 数据库,否则即使您复制到正确的路径,应用程序也无法识别它。

于 2012-03-29T04:44:36.010 回答
4

实际上SQLiteOpenHelper负责您的数据库创建、升级等等。如果要以编程方式创建表,则必须在类的 onCreate 方法中编写创建表查询SQLiteOpenHelper。如果要在先前创建的数据库之后更新数据库,则可以在 onUpgrade 方法中编写修改后的表的查询,只有您将拥有更改数据库版本。

如果您已经在外部创建了一个数据库并且想要使用该数据库,那么您必须将该数据库放在 assets 文件夹中,并将该文件复制到位于该文件夹中的数据库文件/data/data/packagename/databases夹中。

这是将数据库从资产复制到数据库文件夹的示例

private static boolean copyDataBase(Context c) throws IOException {
    String DB_PATH = "/data/data/" + c.getPackageName() + "/databases/";
    AssetManager mg = c.getResources().getAssets();
    InputStream myInput = null;

    try {
        myInput = mg.open(DATABASE_NAME);

    } catch (IOException ex) {
        return false;
    }

    if (myInput != null) {
        String outFileName = DB_PATH + DATABASE_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[8000];
        int length;

        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();

        Log.d(TAG, "Database is copied");
        return true;
    }
    return false;
}

这是检查数据库及其副本版本的方法

public void copyDatabase() {

    try {
        SharedPreferences preferences = c.getSharedPreferences(c.getPackageName(), Context.MODE_PRIVATE);
        if (checkDataBase(c)) {
            if (preferences.getInt("dbversion", 0) != 0) {
                c.deleteDatabase(DatabaseHelper.DATABASE_NAME);
            }

        }
        getReadableDatabase();
        close();
        if (copyDataBase(c)) {
            Editor editor = preferences.edit();
            editor.putInt("dbversion", DatabaseHelper.DATABASE_VERSION);
            editor.commit();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这是检查数据库是否已经存在的示例?

public static boolean checkDataBase(Context c) {
    File f = new File("/data/data/" + c.getPackageName() + "/databases/"
            + DATABASE_NAME);
    if (!f.exists())
        return false;
    SQLiteDatabase checkDB = null;
    try {
        checkDB = SQLiteDatabase
                .openDatabase("/data/data/" + c.getPackageName()
                        + "/databases/" + DATABASE_NAME, null,
                        SQLiteDatabase.OPEN_READONLY);
        checkDB.close();
    } catch (SQLiteException e) {
        e.printStackTrace();
    }
    return checkDB != null ? true : false;
}
于 2012-03-29T04:46:45.697 回答
2

如果数据库不存在,则调用它SQLiteOpenHelper。如果数据库模式已更改并需要升级,onCreate()则调用它。onUpgrade()所以,你的问题的答案是:

于 2012-03-29T09:59:53.240 回答