【问题标题】:Android Sqlite not updating prepopulated databaseAndroid Sqlite 不更新预填充的数据库
【发布时间】:2021-12-13 18:52:43
【问题描述】:

我在我的 android 应用程序中使用预填充的 sqlite 数据库。现在的问题是当我更新数据库中的数据并增加数据库版本onUpgrade() 方法时,我的数据库没有更新。任何帮助将不胜感激。

这是我的 DatabaseHelper.java

public class DatabaseHelper extends SQLiteOpenHelper {

    private Context mContext;
    private SQLiteDatabase mDatabase;

    public DatabaseHelper(Context context) {
        super(context, Constants.DB_NAME, null, Constants.DB_VERSION);
        this.mContext = context;


        // Copy the Database if no database exists
        if (!DatabaseHandler.checkDataBase(context)) {
            DatabaseHandler.copyDataBase(context, Constants.DB_NAME, Constants.DB_VERSION);
        }
        mDatabase = this.getWritableDatabase();
    }


    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }


    public void openDatabase() throws SQLException {
        mDatabase = this.getWritableDatabase();
    }

    public Cursor getAllQuotes() {

        String query = "SELECT * FROM " + Constants.TABLE_QUOTE;

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = null;
        try {
            openDatabase();
            cursor = db.rawQuery(query, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cursor;
    }


    @Override
    public synchronized void close() {
        if (mDatabase != null)
            mDatabase.close();
        super.close();
    }
}

这是我的DatabaseHandler.java

【问题讨论】:

    标签: android-sqlite android-room android-database android-room-prepackageddatabase


    【解决方案1】:

    现在的问题是当我更新数据库中的数据并增加数据库版本时 onUpgrade() 方法被调用但我的数据库没有更新。

    假设您的意思是您已经更新了预填充的数据库,因此希望应用新的预填充数据库(已放入 assets 文件夹)。然后需要调用相应的DatabaseHandler的copyDatabase方法。

    不建议在onUpragde 方法中执行此操作,因为在此阶段数据库已经打开/分配。

    建议在 SQLiteOpenHelper 子类的 super 调用进行检查之前检查是否有升级到期。

    DatabaseHandler 有一个方法getVersionFromAssetFile 检索资产数据库的版本,但不检索数据库的版本。

    如果资产文件中的版本用于检查编码数据库版本 (DB_VERSION),则由于资产文件受到保护且无法在应用程序内更改,使用资产版本测试编码数据库版本将导致每次运行应用程序时不匹配(升级)。

    因此,您可以根据数据库版本检查编码版本以检测升级。

    因此,您可以将 DatabaseHandler 类更改为包括:-

    /**
     * Get the SQLite user_version from the DB
     * @param context   used to get the database path
     * @param databaseName  the name of the database (assumes database is stored in default location)
     * @return the version number as stored in the Database
     */
    public static int getVersionFromDatabaseFile(Context context, String databaseName) {
        InputStream is;
        try {
            is = new FileInputStream(context.getDatabasePath(databaseName));
        } catch (IOException e) {
            return OUCH;
        }
        return getDBVersionFromInputStream(is);
    }
    

    然后您可以修改确定是否应复制资产以在数据库不存在时复制资产或如果数据库存在以复制资产(新)的测试(如果数据库版本低于编码版本) .

    例如:-

    public DatabaseHelper(Context context) {
        super(context, Constants.DB_NAME, null, Constants.DB_VERSION);
        this.mContext = context;
    
        // Copy the Database if no database exists
        // **NEW** or copy the Database if the database version is less than the
        // coded version (DB_VERSION)
        if (!DatabaseHandler.checkDataBase(context)) {
            DatabaseHandler.copyDataBase(context, Constants.DB_NAME, Constants.DB_VERSION);
        } else {
            if (DatabaseHandler.getVersionFromDatabaseFile(context,Constants.DB_NAME) < Constants.DB_VERSION) {
                DatabaseHandler.copyDataBase(context,Constants.DB_NAME,Constants.DB_VERSION);
            }
        }
        mDatabase = this.getWritableDatabase();
    }
    
    • 请注意,只要编码版本(DB_VERSION 增加),上述内容就会复制资产。更复杂的升级处理可以通过使用getVersionFromDBInAssetFolder 来考虑资产数据库的版本,例如

            if (DatabaseHandler.getVersionFromDatabaseFile(context,Constants.DB_NAME) < Constants.DB_VERSION
                    && DatabaseHandler.getVersionFromDBInAssetFolder(context,Constants.DB_NAME) == Constants.DB_VERSION
            ) {
                DatabaseHandler.copyDataBase(context,Constants.DB_NAME,Constants.DB_VERSION
                );
            }
      
      • 因此,只有当资产数据库中的版本与更新后的 DB_VERSION 相同时,资产副本才会发生
    • 注意上面的代码是in-principal code,没有运行过,所以可能会有一些错误。

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      相关资源
      最近更新 更多