SQLiteOpenHelper onCreate运行两次?

时间:2014-09-30 18:00:02

标签: android sqlite sqliteopenhelper

在我的数据库处理程序类(扩展SQLiteOpenHelper)中,我有onCreate()方法:

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(CREATE_TABLE_TASKS); 
    db.execSQL(CREATE_TABLE_CONTACTS);
}

有时(非常罕见,但仍然)这会导致崩溃,因为显然第一个表已经存在。显然我可以(并且确实)在语句中添加IF NOT EXISTS来解决这个问题,但我想知道的是,如果表已经存在,onCreate()将会运行的情况是什么。这通常不会发生,所以我可能搞砸了,但我无法弄明白。

1 个答案:

答案 0 :(得分:3)

  

我想知道如果表已经存在,onCreate()将会运行的情况是什么

竞争条件:多个线程尝试通过getReadableDatabase()getWritableDatabase()暂停数据库。

特别是如果线程在code中的getVersion()setVersion()之间交错:

242            final int version = db.getVersion();
243            if (version != mNewVersion) {
...
251                    if (version == 0) {
252                        onCreate(db);
253                    } else {
254                        if (version > mNewVersion) {
255                            onDowngrade(db, version, mNewVersion);
256                        } else {
257                            onUpgrade(db, version, mNewVersion);
258                        }
259                    }
260                    db.setVersion(mNewVersion);

有一个非常重要的处理和一些磁盘I / O,因此两个线程在这场比赛中结束并不难。

可能的解决方案:

  • 同步:使用Java同步原语来防止其他线程同时尝试创建数据库。

  • Singleton同步。确保只有一个数据库助手。

  • 仅在单个线程中访问数据库。