2

assets/オフラインで作成してディレクトリに配置した、事前入力されたDBがあります。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);");
}

アプリを実行すると、列が見つからないというエラーが発生します(上記のスキーマはDBアクセスコードが期待するものと一致せず、列の数が不足しています。アプリの2回目の実行で、android_metatdata破損してからimportAssets()呼び出しの前にSQLコードを試してみたところ、同様に悲惨な結果になりました。

そのため、私が行っているファイルコピーimportAssets()は、基本的に。によって切り捨てられていると思い始めていますonCreate()。私は正しいですか?onCreate()SQLを直接使用してDBを作成する唯一の方法はありますか?この関数を使用して、既製のDBをコピーすることはできません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");
    }
}

SQLiteOpenHelperコンストラクター内でファイルのコピーを行うという提案を他の場所で見ましたimportAssets()が、DBを使用するたびにコンストラクターが呼び出されるため、ファイルの存在を手動でチェックする必要があります。また、onCreate()それを回避する方法は見当たらないが、私がやりたいことには事実上役に立たないだろう。

4

1 に答える 1

2

私は今、私の疑いが正しかったと確信しています。のonCreate()関数は、スーパークラスコンストラクターの呼び出しSQLiteOpenHelperのパラメーターで指定されたDBファイルを作成します。次に、さまざまなDBライブラリを使用してname、関数内からこのDBファイルを変更(テーブル、データの追加、テーブルの変更など)することを想定しています。他の場所からファイルをコピーすると、切り捨てられます。onCreate()

どのように、またはなぜこれを行うのかはわかりませんが、これはonCreate()、DBをそのままコピーして「作成」するのに役に立たないので、そこからassets/必要なものがあります。コンストラクターに移動importAssets()し、適切なチェックを追加して、既に存在する場合に上書きしないようにしました。何も入っonCreate()ていないので、他の場所で起こっていることを混乱させることはないようです。

SQLiteOpenHelperそれにはSQLiteスクリプトを実行する機能が本当に必要だと思います。このようにして、SQLの長いチャンクをJavaコードにハードコーディングする必要はありません。本当にやりたいのは、DBセットアップを取得することだけです。

于 2012-11-17T22:08:02.133 に答える