2012-03-02 14 views
0

私はそれぞれのデータベーステーブルを担当する一連のクラスを持つプロジェクトを持っています。データベースがロックされているため、Android onUpgrade()が失敗します。どうすればよいですか?

各テーブル管理クラスが取得接続、実行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 

(ONUPGRADEにデータを移行するためのクラスを管理する私のテーブルを使用する方がはるかに簡単になります)、db.execSQL()文よりも優れているか、またはonUpgrade()のSQLiteDatabaseを使用するすべてのCRUDメソッドを書き直してください。

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

ありがとうございます!

+0

これまでにこの問題が発生しました。それを絞り込むのに役立つちょっとした質問ですが、あなたはどんなスレッディングをしていても、このインスタンスのSQLiteOpenHelperはシングルトンですか?アクセスポイントは1つだけにしてください(http://stackoverflow.com/a/3689883/429047)。 –

+0

私はSQLiteOpenHelperを継承するクラスを持っています。静的インスタンスを返すのではなく、このクラスをインスタンス化します。私は、リファレンスがなくなったシングルトンにContextリファレンスを渡すことが大丈夫かどうか分からなかった。また、各CRUDメソッドで接続を開いたり閉じたりします。 – Shellum

+0

私が理解できないのは、アップグレードの特定のテーブルで失敗する理由です。アップグレードする前にandroid_metadataが存在する必要があります。ヘルパーからonUpgradeメソッドを投稿できますか? –

答えて

1

私は答えを得られなかったので、私は開発者のハングアウトについて尋ねました。

Androidデベロッパーハングアウトチームによれば、onUpgradeは構造の変更のみを対象としており、実際にはデータの移行/操作は対象ではありません。あなたはONUPGRADE()にいるときに、あなたはSQLiteDatabaseはONUPGRADE()があなたを提供することを取り扱う使用する必要が

db = dbAdapter.getWritableDatabase(); 

2

はここにあなたの問題です。だからあなたのソリューションは、1つの以上の引数を取るために、あなたのaddPerson機能を書き換えることである - SQLiteDatabaseハンドル:

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

あなたが他の場所プロジェクト内からaddPerson()を呼び出す必要がある場合には、(人人)あなたの現在のaddPersonを保ちますそれを行うには、 db = dbAdapter.getWritableDatabase() を呼び出して、dbをaddPerson()の2引数バージョンに渡します。

関連する問題