2012-03-02 5 views
0

例外:Androidでは、これはSQLiteDatabaseヘルパーを設定する正しい方法ですか?

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

私のアプリが正常に動作してONUPGRADE()が呼び出されたときを除いて、何デシベルの問題を持っていません。

onUpgradeが自動的に呼び出されると、以下のCarManagerクラスを使用してアップグレードに必要なデータ操作を実行しようとします。これは、dbがロックされているため失敗します。

行うには、通常のものでなければなりませんように、これはと思われるので、(2つのクラスが、ヘルパーとテーブルマネージャに従ってください)私が正しく、次のコードを構造化されてはならないようだ。

public class DbHelper extends SQLiteOpenHelper { 

    private Context context; 

    //Required constructor 
    public DbAdapter(Context context) 
    { 
     super(context, "my_db_name", null, NEWER_DB_VERSION); 
     this.context = context; 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
     overrideDB = db; 
     CarManager.migrateDataForOnUpgrade(context); 
    } 
} 


public class CarManager { 

    DbHelper dbHelper; 

    public CarManager(Context context) 
    { 
     dbHelper = new DbHelper(context); 
    } 

    public void addCar(String make, String model) 
    { 
     ContentValues contentValues = new ContentValues(); 
     contentValues.put("make", make); 
     contentValues.put("model", model); 

     SQLiteDatabase db = dbHelper.getWritableDatabase(); 
     db.insert("car", null, contentValues); 
     db.close(); 
    } 

    public static void migrateDataForOnUpgrade() 
    { 
     //Code here that migrates data when onUpgrade() is called 
     //Db lock happens here 
    } 
} 

どれでもアイデア? テーブル管理者(例:dao)はこれとは異なる方法で設定しますか?

編集:私はGoogleのチーム@ Android開発者の時間に話をしました。彼らはonUpgrade3が決して構造変化(変更)のようなことをすることはないと言いました。そう、はい、今のところ多くの場合に使用されなければならないハックがあるようです。

+0

好奇心のために、OrmLite(http://ormlite.com/)はDAOクラスを設定する良い方法です。 – jcxavier

+1

例外を投稿する – Jack

+0

例外は何ですか? – drulabs

答えて

0

Applicationクラスを拡張して次のモデルを使用します。私は...単に次んデシベルヘルパーを使用する必要がある任意のクラスにその時から、他のすべてのアプリのコンポーネントを使用して私のデシベルヘルパーの単一の静的インスタンス...

public class MyApp extends Application { 

    protected static MyAppHelper appHelper = null; 
    protected static MyDbHelper dbHelper = null; 

    @Override 
    protected void onCreate() { 
     super.onCreate(); 
     ... 
     appHelper = new MyAppHelper(this); 
     dbHelper = MyAppHelper.createDbHelper(); 
     dbHelper.getReadableDatabase(); // Trigger creation or upgrading of the database 
     ... 
    } 
} 

を維持

if (MyApp.dbHelper == null) 
    MyApp.appHelper.createDbHelper(...); 
// Code here to use MyApp.dbHelper 
+0

コンテキスト参照MyAppHelper.createDbHelper(...)を渡す必要があると仮定します。たとえば、アクティビティクラスから 'this'を渡した場合、その参照が古くなるという印象を受けました。どう思いますか? – Shellum

+1

私は自分のコードをチェックしました。私は実際には、アプリケーションのコンテキストを参照を保持する 'アプリヘルパー'に渡します。それは 'createDbHelper()'メソッドの一部として 'appヘルパー'によって 'dbヘルパー'に渡されます。アプリケーションコンテキストへの参照を維持することとの違いは、アプリケーションインスタンスが1つしか存在せず、そのコンテキストが有効であることです。アクティビティーは何度も作成/破壊することができます。また、任意のアクティビティー・クラスの複数のインスタンスを持つことも可能です。したがって、POJOがアクティビティー・コンテキストを保持することは決してうまくありません。 – Squonk

関連する問題