2012-03-02 95 views
0

例外:在Android中,這是設置SQLiteDatabase助手的正確方法嗎?

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

我的應用程序工作正常,並沒有DB的問題,除了當onUpgrade()被調用。

當onUpgrade被自動調用時,它會嘗試使用下面的CarManager類來完成升級所需的數據操作。這因爲數據庫被鎖定而失敗。

因爲這似乎應該是做一個正常的事情,看來我不能構建正確下面的代碼(兩班跟隨,輔助和一張桌子經理):

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)?

編輯:我跟谷歌團隊@ android開發者小時談過,他們說onUpgrade3從來沒有做過像結構變化(改變)的任何事情。所以,是的,現在好像有一些必須在許多情況下使用的黑客。

+0

爲了好奇,OrmLite(http://ormlite.com/)是設置DAO類的好方法。 – jcxavier 2012-03-02 18:13:36

+1

發佈例外 – Jack 2012-03-02 18:14:43

+0

什麼是例外? – drulabs 2012-03-02 18:16:52

回答

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

從此這需要使用DB助手根本就下列任何一類......

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

我認爲你需要傳遞一個Context引用MyAppHelper.createDbHelper(...)我的印象是這個引用可能會變成陳舊(例如,如果你從Activity類中傳入'this')。你怎麼看? – Shellum 2012-03-02 19:00:42

+1

我剛剛檢查了我的代碼。實際上,我將應用程序上下文傳遞給了具有引用的「應用程序助手」。然後它被'app helper'作爲'createDbHelper()'方法的一部分傳遞給'db helper'。維護對應用程序上下文的引用的區別在於,只能有一個應用程序實例,並且上下文在其生命週期內是有效的。活動可以反覆創建/銷燬,也可以有任何給定活動類的多個實例,因此POJO永遠不會持有活動上下文。 – Squonk 2012-03-02 19:15:06

相關問題