如果有人卸载并清除所有数据,onUpgrade() 如何工作?

How onUpgrade() works if anyone uninstall and cleared all data?

几天来我一直在开发一个 android 应用程序,使用 SQLite 作为数据库。有时我不得不添加专栏。为此,我只是更改数据库版本并记下 onUpgrade() 中的更改,如下所示:

db.execSQL("ALTER TABLE "+TABLE_EMPLOYEE+" ADD "+COLUMN_EMPLOYEE_MOBILE+" TEXT");

当应用程序仍安装在手机中时适用。但是当应用程序之前未安装或卸载并清除所有数据和缓存时,它会显示错误。因为在检查版本时,它只有一个版本。如何解决?

您的 onCreate() 应该设置一个适合您当前数据库版本的新数据库。 onUpgrade() 仅在存在旧版本的数据库文件时调用。

我建议您阅读这篇文章SQLite以了解如何设置数据库。

来自文档: 你有这个 DbHelper 并且你有这些覆盖:

onCreate

Called when the database is created for the first time. This is where the creation of tables and the initial population of the tables should happen.

onUpgrade

Called when the database needs to be upgraded. The implementation should use this method to drop tables, add tables, or do anything else it needs to upgrade to the new schema version.

onDowngrade

Called when the database needs to be downgraded. This is strictly similar to onUpgrade(SQLiteDatabase, int, int) method, but is called whenever current version is newer than requested one. However, this method is not abstract, so it is not mandatory for a customer to implement it. If not overridden, default implementation will reject downgrade and throws SQLiteException

有了这些方法就可以了,不用担心旧版本和新版本。

class FeedReaderDbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(SQL_CREATE_ENTRIES)
    }
    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        db.execSQL(SQL_DELETE_ENTRIES)
        onCreate(db)
    }
    override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        onUpgrade(db, oldVersion, newVersion)
    }
    companion object {
        // If you change the database schema, you must increment the database version.
        const val DATABASE_VERSION = 1
        const val DATABASE_NAME = "FeedReader.db"
    }
}

onCreate() 方法中,您必须具有创建 table 的代码,因为您希望它们位于最新版本的数据库中。

因此,当您部署第一个版本时,它看起来像:

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_EMPLOYEE_TABLE = "CREATE TABLE " + 
        TABLE_EMPLOYEE + " ("+ 
        COLUMN_ID + " INTEGER PRIMARY KEY, " + 
        COLUMN_EMPLOYEE_NAME + " TEXT)";
    db.execSQL(CREATE_EMPLOYEE_TABLE);
}

但在第 2 版中,由于您在 table 中引入了一个新列,因此它应该像:

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_INPUT_TABLE = "CREATE TABLE " + 
        TABLE_EMPLOYEE + " ("+ 
        COLUMN_ID + " INTEGER PRIMARY KEY, " + 
        COLUMN_EMPLOYEE_NAME + " TEXT, " +
        COLUMN_EMPLOYEE_MOBILE + " TEXT)"; // new column
    db.execSQL(CREATE_INPUT_TABLE);
}

只有在没有安装数据库的情况下才会调用onCreate()方法。

因此,当您部署数据库的第二个版本时,如果用户已经安装了第一个版本并且旧数据库仍然存在,onCreate()不会 被调用,但 onUpgrade() 将使用您问题中的代码调用,并将更改现有的 table.

如果用户决定卸载第一个版本然后安装第二个版本,然后 onCreate() 将被调用,因为没有安装数据库,它会创建 table(s ) 在该版本中如您所愿。

不是这样,onCreate()onUpgrade() 不会在用户安装应用程序时自动调用。
它们由第一次调用 getReadableDatabase()getWriteableDatabase().

调用