2012-03-02 99 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

相关问题