是否真的有必要在每次应用程序启动时创建SQLite表?

时间:2012-03-29 04:37:27

标签: android sqliteopenhelper android-sqlite

我注意到在多个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目录?有什么建议吗?

3 个答案:

答案 0 :(得分:5)

我觉得你在这里误会了。构造SQLiteOpenHelper对象时,它将检查SQLite数据库是否存在,如果不存在,它将调用其 onCreate()方法(通常开发人员实现create database 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.app等,此路径适用于您设备的Android操作系统,不适用于Windows)。

您的情况是,您希望使用已存在的数据库,因此需要实现一个检查数据库是否存在的函数,如果不将数据库复制到数据库路径 / data / data / {packagename} / databases / ,并在您的应用启动时调用该功能。如何做到这一点已在这里得到解答How to copy existing database from one app to another。如果您不知道http://www.wiseandroid.com/post/2010/06/14/Android-Beginners-Intro-to-Resources-and-Assets.aspx

,此处还可以参考访问资产文件

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

答案 1 :(得分:4)

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

如果您已经在外部创建了数据库,并且想要使用该数据库,则必须将该数据库放在assets文件夹中,并将该文件复制到驻留在/data/data/packagename/databases文件夹中的databases文件夹中。 / p>

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

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

答案 2 :(得分:2)

如果数据库不存在,SQLiteOpenHelper会调用onCreate()。如果数据库架构已更改且需要升级,则调用onUpgrade()。因此,您的问题的答案是: