【问题标题】:SQLiteOpenHelper onCreate running twice?SQLiteOpenHelper onCreate 运行两次?
【发布时间】:2014-11-25 10:54:18
【问题描述】:

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

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

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

【问题讨论】:

  • 我已经和SQLiteOpenHelper 合作了快 3 年了,我从未见过这个错误...
  • 我偶尔也会遇到一些 SQLiteDatabaseLockedExceptions,因为我有一堆数据库处理程序类实例在做一些事情,有时是同时做的。这会导致错误吗?如果是这样,那么当我修复数据库锁定问题时,这也可能会消失。
  • 哦,如果你有其他线程在数据库上做事,那么是的,这是正常的。另一个线程已经创建了这个表。我建议您在创建数据库之前不要产生其他线程。
  • 是的,其他线程同时在做事。是否可以通过对数据库处理程序类使用单例模式来解决此问题?
  • 如果您在应用程序未卸载的位置创建表,例如您在 /sdcard/myapp/data 创建表,然后重新安装应用程序,这可能会发生。无论如何,如果不存在则创建是数据库的最佳实践。您可能只是在修复损坏的安装习惯。

标签: android sqlite sqliteopenhelper


【解决方案1】:

我想知道如果表已经存在,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 同步原语防止其他线程同时尝试创建数据库。

  • 具有同步的单例。确保只有一个数据库助手。

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

【讨论】:

  • 两个线程如何在getVersion()setVersion() 之间交错?该代码块是私有方法getDatabaseLocked() 的一部分,它只能从同步代码中调用。
  • @Matt 同步在助手实例上。如果您有两个帮助程序实例,则无济于事。
  • 好的,误解了你的答案。这就是为什么您建议将单例作为可能的解决方案之一。
  • 另外,对于所有认为自己已经将SQLiteOpenHelper 用作单例的人:检查您声明的任何Android 组件是否使用android:process=...,因为这将导致Application.onCreate() 被第二次调用时间。我正在从那里启动迁移逻辑。不要忘记检查所有依赖项。例如,ACRA 4.8.1 在单独的进程中启动服务。
猜你喜欢
  • 2014-11-11
  • 2016-09-17
相关资源
最近更新 更多