1

それぞれのデータベース テーブルを担当する一連のクラスを含むプロジェクトがあります。

各テーブル管理クラスには、接続の取得、crud 操作の実行、接続の終了のパターンに従う CRUD メソッドが含まれています。

public class PersonManager {

    SQLiteDatabase db;
    DbAdapter dbAdapter; //This is a subclass of SQLiteOpenHelper

    public void addPerson(Person person)
    {
        ContentValues contentValues = new ContentValues();
        contentValues.put("email", person.email);
        contentValues.put("first_name", person.firstName);

        db = dbAdapter.getWritableDatabase();
        db.insert("person", null, contentValues);
        db.close();
    }

    ...other crud/utility methods omitted...
}

onUpgrade() を使用してデータベースをアップグレードしているため、データベースがロックされている問題に遭遇しました。

正確なエラー メッセージは次のとおりです。

CREATE TABLE android_metadata failed
Failed to setLocale() when constructing, closing the database
android.database.sqlite.SQLiteException: database is locked

onUpgrade は次のいずれかを意味しているようです。

1 run db.execSQL() calls or
2 use helper classes that use onUpgrade()'s SQLiteDatabase rather than their own

テーブル管理クラスを使用して、db.execSQL() ステートメントよりも onUpgrade() でデータを移行するか、すべての CRUD メソッドを書き直して onUpgrade() の SQLiteDatabase を取得する方がはるかに簡単です。

データベースへのアクセスを正しく設定していますか? 上記のコードが正しいパターンに従っている場合、この問題を解決するにはどうすればよいですか?

ありがとう!

4

2 に答える 2

3

問題は次のとおりです。

db = dbAdapter.getWritableDatabase();

onUpgrade() にいるときは、onUpgrade() が提供する SQLiteDatabase ハンドルを使用する必要があります。したがって、解決策は、addPerson 関数を書き直して、もう 1 つの引数 (SQLiteDatabase ハンドル) を取ることです。

public void addPerson(Person person, SQLiteDatabase db) {...}

プロジェクトの他の場所から addPerson() を呼び出す必要がある場合は、現在の addPerson(Person person) 関数を保持し、その関数に db = dbAdapter.getWritableDatabase() 呼び出しを実行させ、2 引数バージョンの addPerson( に db を渡します。 )。

于 2015-03-18T17:23:50.700 に答える
1

回答が得られなかったので、開発者のハングアウトで質問しました。

Android デベロッパー ハングアウト チームによると、onUpgrade は構造の変更のみを目的としており、実際にはデータの移行や操作を目的としていません。

于 2012-06-22T19:15:47.980 に答える