Android apk更新后如何更新域中的初始数据?

Android apk更新后如何更新域中的初始数据?,android,realm,Android,Realm,在应用程序中有一个领域数据库,其中包含初始数据和用户添加的数据。即使在更新之后,用户添加的数据也应保留在设备上。初始数据是通过类添加的 public class RealmInitialData implements Realm.Transaction { @Override public void execute(Realm realm){ //initial data Items item = new Items(); item.s

在应用程序中有一个领域数据库,其中包含初始数据和用户添加的数据。即使在更新之后,用户添加的数据也应保留在设备上。初始数据是通过类添加的

public class RealmInitialData implements Realm.Transaction {

    @Override
    public void execute(Realm realm){
     //initial data
        Items item = new Items();
        item.setName("Fragrance");
        item.setTimestamp(System.currentTimeMillis());
        realm.insertOrUpdate(item);
    }
    @Override
    public int hashCode() {
        return RealmInitialData.class.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && obj instanceof RealmInitialData;
    }
}
配置(位于扩展应用程序类的类中)如下所示:

RealmConfiguration realmConfig = new RealmConfiguration.Builder()
                .name("tasky.realm")
                .schemaVersion(2)
                .migration(new Migration())
                .initialData(new RealmInitialData())
                .build();
public class RealmMigrationAgent implements RealmMigration
{
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        if (oldVersion == 0) {
            schema.get("InventDisableObject").addField("Reason", int.class);
            oldVersion++;
        }

        if (oldVersion == 1) {
            if (!schema.get("ActionObject").hasField("Annual"))
                schema.get("ActionObject").addField("Annual", boolean.class);
            oldVersion++;
        }
        if (oldVersion == 2) {
            if (!schema.get("ActionObject").hasField("Hash"))
                schema.get("ActionObject").addField("Hash", String.class);
            if (!schema.get("ActionObject").hasField("Manual"))
                schema.get("ActionObject").addField("Manual", boolean.class);
            oldVersion++;
        }
        if (oldVersion == 3) {
            if (!schema.get("OutletObject").hasField("Code"))
                schema.get("OutletObject").addField("Code", String.class);
            oldVersion++;
        }
    }
}

如果我在RealmInitialData中更改/添加要更新的内容,则用户应用程序上的数据不会更改。如何既更改初始数据(添加或重写某物),又不更改用户的数据?

您必须实现realmimmigration并将其传递给
RealmConfiguration.Builder().migration()
。 大概是这样的:

RealmConfiguration realmConfig = new RealmConfiguration.Builder()
                .name("tasky.realm")
                .schemaVersion(2)
                .migration(new Migration())
                .initialData(new RealmInitialData())
                .build();
public class RealmMigrationAgent implements RealmMigration
{
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        if (oldVersion == 0) {
            schema.get("InventDisableObject").addField("Reason", int.class);
            oldVersion++;
        }

        if (oldVersion == 1) {
            if (!schema.get("ActionObject").hasField("Annual"))
                schema.get("ActionObject").addField("Annual", boolean.class);
            oldVersion++;
        }
        if (oldVersion == 2) {
            if (!schema.get("ActionObject").hasField("Hash"))
                schema.get("ActionObject").addField("Hash", String.class);
            if (!schema.get("ActionObject").hasField("Manual"))
                schema.get("ActionObject").addField("Manual", boolean.class);
            oldVersion++;
        }
        if (oldVersion == 3) {
            if (!schema.get("OutletObject").hasField("Code"))
                schema.get("OutletObject").addField("Code", String.class);
            oldVersion++;
        }
    }
}
为每个新方案版本增量添加方案更新。
我可以看到您有一些类
迁移
是出于迁移的原因-您能提供它的代码吗?

我也有同样的问题,我找到了解决方法。例如,如果您的新版本是7,请尝试使用
SharedRealm.getInstance(config).getSchemaVersion()
Realm.setDefaultConfiguration(config)之前获取旧版本6
,然后您可以在
setDefaultConfiguration
哪个旧版本<7之后更新旧域数据。这可以帮助您:

RealmConfiguration config = new RealmConfiguration.Builder()
            .schemaVersion(7)
            .migration(new RealmMigration() {
                @Override
                public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
                    RealmSchema schema = realm.getSchema();
                    if(oldVersion == 6) {
                        schema.get("ImageRealm")
                                .addField("isSelected", Boolean.class, FieldAttribute.REQUIRED)
                                .addField("isLow", Boolean.class, FieldAttribute.REQUIRED);
                        oldVersion++;
                    }
                }
            }).build();

    SharedRealm sharedRealm = SharedRealm.getInstance(config);
    long oldVersion = sharedRealm.getSchemaVersion();

    Realm.setDefaultConfiguration(config);
    long newVersion = Realm.getDefaultInstance().getVersion();

    // 如果有历史记录,更新状态
    if (oldVersion < 7) {
        Realm.getDefaultInstance().executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                RealmResults<DocRealmBean> allData = realm.where(DocRealmBean.class).findAll();
                for (DocRealmBean bean : allData) {
                    bean.state = "0";
                }
            }
        });
    }
RealmConfiguration config=newrealmconfiguration.Builder()
.阴谋厌恶(7)
.迁移(新的RealmMigration(){
@凌驾
public void migrate(dynamicrelm领域、long oldVersion、long newVersion){
RealmSchema schema=realm.getSchema();
如果(旧版本==6){
schema.get(“ImageRealm”)
.addField(“isSelected”,Boolean.class,FieldAttribute.REQUIRED)
.addField(“isLow”,Boolean.class,FieldAttribute.REQUIRED);
旧版本++;
}
}
}).build();
SharedRealm SharedRealm=SharedRealm.getInstance(配置);
long oldVersion=sharedRealm.getSchemaVersion();
Realm.setDefaultConfiguration(配置);
long newVersion=Realm.getDefaultInstance().getVersion();
// 如果有历史记录,更新状态
如果(旧版本<7){
Realm.getDefaultInstance().executeTransaction(新Realm.Transaction()){
@凌驾
公共void执行(领域){
RealmResults allData=realm.where(DocRealmBean.class).findAll();
for(DocRealmBean:allData){
bean.state=“0”;
}
}
});
}

基本上,我没有从models类中添加/删除任何字段。我只需要在更新后更改数据库初始数据。所以迁移并不能解决问题。问题出在这个字符串中。initialData(new RealmInitialData())-它只有在安装应用程序时才会出现。更新后我也需要它。初始化数据的帮助()说它只在两种情况下工作:创建新数据库,如果需要删除RealMifMigrations(或类似的-记不清),则将其设置为true(这也会销毁数据库中的任何数据)。所以,若您需要添加数据并保留以前的数据—我可以假设—更新方案版本并使用迁移代理严格添加数据,或者使用数据库中的某些值来更新上一个版本,请对照新版本进行检查,若发生更新—则添加,或者类似的操作。Ok。那么,我应该在迁移中写些什么来“严格地添加数据”?它将再次进入RealmInitialData类,或者我需要创建另一个类来添加这些新组件。我应该如何在迁移中包含这些内容?可能与您在RealmInitalData中添加对象时使用的代码相同。或者,如果在
onCreate()或构造函数中添加数据,则创建它的对象。如果(oldVersion==0){//在此处创建适合此版本的初始数据对象}。。。不要忘记保存所有版本的历史记录,以便用户可以从任何版本更新到最后一个版本。对于任何新版本,代码都将以增量方式执行。但从未使用迁移类添加任何数据-可能存在一些问题。。如果您先尝试第二种变体,效果会更好。