如果用户跳过更新,如何处理领域迁移
How to handle realm migration if users skip updates
所以我们有一个场景,其中用户拥有 1.0 版的应用程序。 2.0版本出来了,但是用户不更新。当 3.0 版本出来时,用户决定更新。
因为用户没有更新过app,realm文件也没有更新,所以从1.0版本迁移到3.0版本时,Migration.execute
的version
参数会有值1 而不是 2。
当用户直接安装应用程序的 2.0 版然后迁移到 3.0 版时,也存在问题。和前面的情况一样,version
参数会出错。
有没有办法妥善处理这些情况?
我不是 Realm
大师,也没有在实际项目中使用 Realm
,但这种方法应该有效:
假设您使用 this 迁移示例:
您需要在项目中保存一个额外的 属性(例如 SharedPreferences
)- latestMigrationVersion
。默认情况下,latestMigrationVersion = 0
,这意味着我们还没有 运行 迁移。
修改你Migration.java
class如下:
@Override
public long execute(Realm realm, long version) {
// check if the previous migration took place
if (version > 0 && version - 1 > latestMigrationVersion) {
// user missed migration
// then we need to run previous missed migrations before
version = latestMigrationVersion;
}
// do migrations as described in the example.
...
// update latestMigrationVersion for future checks
latestMigrationVersion = version;
// save the property locally
}
现在,如果用户直接安装 2.0 版本,将在 2.0 -> 3.0
迁移之前执行所有以前的迁移。
Unit tests
应该可以帮助您检查所有可能的迁移:0.0 -> 3.0
、1.0 -> 2.0
、2.0 -> 3.0
等
实际上 Realm 的 migration example 显示了这种情况。
public class Migration implements RealmMigration {
@Override
public long execute(Realm realm, long version) {
// Step 0
if (version == 0) {
//Do the migration from 0 to 1
version++;
}
// Step 1
// Now the version is at least 1
if (version == 1) {
// Do the migration from 1 to 2
version++;
}
// Step 2
if (version == 2) {
// Do the migration from 2 to 3
version++;
}
// Now you get your final version 3
return version;
}
}
只需一步一步地编写迁移,运行 一个一个地写,直到获得最新的架构版本。对于您的情况,用户可能在这里有一个 Realm db 版本 0,并且 step0 将首先 运行。然后版本在步骤 0 块中跳到 1,然后步骤 1 将 运行 然后。
------------ 用户直接安装版本 3 的更新案例------------
创建领域实例时,代码如下:
RealmConfiguration config = new RealmConfiguration.Builder(this)
.migration(migration)
.schemaVersion(3)
.build();
Realm realm = Realm.getInstance(config);
请注意这里的schemaVersion(3)
。
RealmMigration.execute()
将 仅在需要迁移时执行 。这意味着如果用户直接安装版本 3 而没有在设备上安装任何以前的版本,则不会调用 RealmMigration.execute()
并且在 Realm 文件初始化后, 架构版本将设置为 3 .
就像 beeender 所说的那样,Realm 中的迁移发生了很大变化,对我来说,使 realm (0.84.2) 迁移工作的关键点是:
当你的应用程序有一个没有领域数据库时,schemaVersion 总是 0
指定 schemaVersion。在大多数情况下这是真的,因为你
一旦你可能开始在配置中使用 schemaVersion
需要迁移并且已经 运行 发布了您的应用程序。
schemaVersion 会自动存储,当您的应用程序进行全新安装并且您已经在 schemaVersion 3 时,realm
自动检查是否有异常,如果没有则设置
schemaVersion 为 3,这样您的迁移就不会在不需要时 运行。
这也意味着您不必再存储任何东西
SharedPreferences.
在迁移中,当类型不可为空时,您必须设置新列的所有值,...
可以插入空字符串,但仅当在列上设置 convertColumnToNullable 时才可以插入
所以我们有一个场景,其中用户拥有 1.0 版的应用程序。 2.0版本出来了,但是用户不更新。当 3.0 版本出来时,用户决定更新。
因为用户没有更新过app,realm文件也没有更新,所以从1.0版本迁移到3.0版本时,Migration.execute
的version
参数会有值1 而不是 2。
当用户直接安装应用程序的 2.0 版然后迁移到 3.0 版时,也存在问题。和前面的情况一样,version
参数会出错。
有没有办法妥善处理这些情况?
我不是 Realm
大师,也没有在实际项目中使用 Realm
,但这种方法应该有效:
假设您使用 this 迁移示例:
您需要在项目中保存一个额外的 属性(例如 SharedPreferences
)- latestMigrationVersion
。默认情况下,latestMigrationVersion = 0
,这意味着我们还没有 运行 迁移。
修改你Migration.java
class如下:
@Override
public long execute(Realm realm, long version) {
// check if the previous migration took place
if (version > 0 && version - 1 > latestMigrationVersion) {
// user missed migration
// then we need to run previous missed migrations before
version = latestMigrationVersion;
}
// do migrations as described in the example.
...
// update latestMigrationVersion for future checks
latestMigrationVersion = version;
// save the property locally
}
现在,如果用户直接安装 2.0 版本,将在 2.0 -> 3.0
迁移之前执行所有以前的迁移。
Unit tests
应该可以帮助您检查所有可能的迁移:0.0 -> 3.0
、1.0 -> 2.0
、2.0 -> 3.0
等
实际上 Realm 的 migration example 显示了这种情况。
public class Migration implements RealmMigration {
@Override
public long execute(Realm realm, long version) {
// Step 0
if (version == 0) {
//Do the migration from 0 to 1
version++;
}
// Step 1
// Now the version is at least 1
if (version == 1) {
// Do the migration from 1 to 2
version++;
}
// Step 2
if (version == 2) {
// Do the migration from 2 to 3
version++;
}
// Now you get your final version 3
return version;
}
}
只需一步一步地编写迁移,运行 一个一个地写,直到获得最新的架构版本。对于您的情况,用户可能在这里有一个 Realm db 版本 0,并且 step0 将首先 运行。然后版本在步骤 0 块中跳到 1,然后步骤 1 将 运行 然后。
------------ 用户直接安装版本 3 的更新案例------------
创建领域实例时,代码如下:
RealmConfiguration config = new RealmConfiguration.Builder(this)
.migration(migration)
.schemaVersion(3)
.build();
Realm realm = Realm.getInstance(config);
请注意这里的schemaVersion(3)
。
RealmMigration.execute()
将 仅在需要迁移时执行 。这意味着如果用户直接安装版本 3 而没有在设备上安装任何以前的版本,则不会调用 RealmMigration.execute()
并且在 Realm 文件初始化后, 架构版本将设置为 3 .
就像 beeender 所说的那样,Realm 中的迁移发生了很大变化,对我来说,使 realm (0.84.2) 迁移工作的关键点是:
当你的应用程序有一个没有领域数据库时,schemaVersion 总是 0 指定 schemaVersion。在大多数情况下这是真的,因为你 一旦你可能开始在配置中使用 schemaVersion 需要迁移并且已经 运行 发布了您的应用程序。
schemaVersion 会自动存储,当您的应用程序进行全新安装并且您已经在 schemaVersion 3 时,realm 自动检查是否有异常,如果没有则设置 schemaVersion 为 3,这样您的迁移就不会在不需要时 运行。 这也意味着您不必再存储任何东西 SharedPreferences.
在迁移中,当类型不可为空时,您必须设置新列的所有值,...
可以插入空字符串,但仅当在列上设置 convertColumnToNullable 时才可以插入