28

アプリには Realm を使用します。私たちのアプリはベータ版がリリースされました。次に、レルム オブジェクトの 1 つにフィールドを追加します。だから私は RealmMigration を書かなければならず、私もそれを書きました。ここでの質問は、このレルムの移行をアプリに適用する方法です。何かしたいときはいつでも 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 を削除しました。以前のアプリをアンインストールせずにアプリを再インストールしようとすると、例外が発生しました。ご意見をお聞かせください。

4

2 に答える 2

37

ここで説明されています: 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();
于 2016-03-07T08:29:50.380 に答える
0

これは、アプリケーションに .realm データベースをインポートするために作成したヘルパー クラスです。私の場合、iOS アプリケーションから作成されたデータベースを Android アプリケーションで読み取るだけで済みます。

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() オプションを使用する必要があります。

これが必要なのは、レルムがデフォルトで RealmObject を拡張するすべてのモデルのテーブルが .realm にあるかどうかを確認しようとするためです。また、複数の .realm がある場合、それぞれにいくつかのクラスが含まれます (ただし、すべてではない)。

もう 1 つの有用な情報は、Android への迅速な移行に関するものです。すべての文字列プロパティは、@Required アノテーションを使用して宣言する必要があります (デフォルト値がある場合)。

レルムが「このクラスはこのスキーマに見つかりませんでした」などの奇妙な例外を提供している場合は、アプリを再実行してみてください。通常、実際の問題を示唆する別のエラーが発生しますが、ランダムなエラーが発生することもあります。

于 2016-10-22T19:25:19.407 に答える