正确的Realm Migration Android方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正确的Realm Migration Android方式相关的知识,希望对你有一定的参考价值。

我们为我们的应用程序使用Realm。我们的应用已经发布测试版。现在我想在我们的一个领域对象中添加一个字段。所以我写了RealmMigration,我也写了一个。这里的问题是如何将此Realm迁移应用到我的应用程序。我使用Realm.getInstance()在我想要的时候获取领域实例。请记住,Realm.getInstance()每次都在整个应用程序中使用,我想访问Realm数据库。

那么,我有点询问如何应用这种迁移?任何线索都可能有所帮助。谢谢。

我的RealmMigration如下。

public class RealmMigrationClass implements RealmMigration {
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        if(oldVersion == 0) {
            RealmSchema sessionSchema = realm.getSchema();

            if(oldVersion == 0) {
                RealmObjectSchema sessionObjSchema = sessionSchema.get("Session");
                sessionObjSchema.addField("isSessionRecordingUploading", boolean.class, FieldAttribute.REQUIRED)
                        .transform(new RealmObjectSchema.Function() {
                            @Override
                            public void apply(DynamicRealmObject obj) {
                                obj.set("isSessionRecordingUploading", false);
                            }
                        });


                sessionObjSchema.setNullable("isSessionRecordingUploading",false);
                oldVersion++;
            }

        }
    }

}

public class Session extends RealmObject {

    @PrimaryKey
    private String id;
    @Required
    private Date date;
    private double latitude;
    private double longitude;
    private String location;
    private String note;
    private String appVersion;
    private String appType;
    private String deviceModel;
    private HeartRecording heart;
    private TemperatureRecording temperature;
    private LungsRecording lungs;
    @NotNull
    private boolean isSessionRecordingUploading;
    private boolean sessionInfoUploaded;
    private boolean lungsRecordingUploaded;
    private boolean heartRecordingUploaded;

}

从RealmObject中删除了Getter和Setter以缩短问题。当我尝试重新安装应用程序而不卸载前一个应用程序时发生异常。请指教。

答案

这里描述:https://realm.io/docs/java/latest/#migrations

但实质上,您只是碰撞架构版本并设置如下配置:

RealmConfiguration config = new RealmConfiguration.Builder(context)
    .schemaVersion(2) // Must be bumped when the schema changes
    .migration(new MyMigration()) // Migration to run
    .build();

Realm.setDefaultConfiguration(config);

// This will automatically trigger the migration if needed
Realm realm = Realm.getDefaultInstance();
另一答案

这是我将.realm数据库导入到我的应用程序的帮助程序类。在我的情况下,我只需要阅读从android应用程序中的ios应用程序创建的数据库

public class RealmImporter {
private Activity activity;
private String dbaFullName = "db.realm";
private int rawRealmResource = R.raw.dbRealmResource;


public RealmImporter (Activity activity) {
    this.activity = activity;
    importData();
}


private RealmConfiguration getConfiguration() {
    RealmConfiguration config = new RealmConfiguration.Builder()
            .name(dbaFullName)
            .modules(new MyRealmModule())
            .migration(new RealmMigration() {
                @Override
                public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

                }
            })
            .build();

    return config;
}

public Realm getInstance() {
    Realm realm = Realm.getInstance(getConfiguration());

    return realm;
}

private void importData() {
    copyBundledRealmFile(activity.getResources().openRawResource(rawRealmResource), dbaFullName);

    Realm.init(activity);
}

private String copyBundledRealmFile(InputStream inputStream, String outFileName) {
    try {
        File file = new File(activity.getFilesDir(), outFileName);
        if (file.exists()) {
            return file.getAbsolutePath();
        }
        FileOutputStream outputStream = new FileOutputStream(file);
        byte[] buf = new byte[1024];
        int bytesRead;

        while ((bytesRead = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, bytesRead);
        }

        outputStream.close();
        return file.getAbsolutePath();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}


// Create the module
@RealmModule(classes = { Artigo.class, Comparativo.class, Indice.class, ItemDeArtigo.class})
public static class MyRealmModule{
}
}

如果您有多个领域配置(如果需要导入多个.realm文件),则需要创建RealmModule类并使用RealmConfiguration.Builder上的.modules()选项。

这是必需的,因为默认领域尝试检查你的.realm是否有扩展RealmObject的所有模型的表,如果你有多个.realm,它们中的每一个都会有你的一些类(但不是全部)。

其他有用的信息是swift到android的迁移。必须使用@Required注释声明所有String属性(如果它们具有默认值)。

如果领域给你一个奇怪的异常,例如“在这个模式中找不到这个类”,尝试重新运行你的应用程序,通常它会给出一个不同的错误,它可以暗示真正的问题,虽然有时它只是给出一个随机错误。

以上是关于正确的Realm Migration Android方式的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 列表中呈现来自 Realm 的数据的正确方法是啥

在 SwiftUI 列表中呈现来自 Realm 的数据的正确方法是啥

如何在 iOS 项目中正确配置 Realm DB 文件 (<db_name>.realm) 的路径?

正确处理Android上的Realm实例

如何在 Realm 中通过 NSDate 属性正确查询对象?

Room Database Migration 无法正确处理 ALTER TABLE 迁移