2016-03-07 21 views
14

私たちはRealmを使用しています。私たちのアプリはベータ版になっています。今私はrealmオブジェクトの1つにフィールドを追加したいと思います。だから私はRealmMigrationを書く必要があり、私も1つを書きました。ここでの質問は、このレルムの移行をアプリに適用する方法です。私はRealm.getInstance()を使用して、何かしたいときはいつでもrealmインスタンスを取得します。 Realm.getInstance()は毎回アプリ全体で使用されているので、Realmデータベースにアクセスしたいと思います。Realm Migration Androidの正しい方法

この移行を適用する方法について私は少し質問しますか?任意のリードが役立ちます。ありがとう。

私の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からゲッターとセッターを削除して質問を短くしました。前のアプリケーションをアンインストールせずにアプリケーションを再インストールしようとすると例外が発生しました。ご意見をお聞かせください。それは、ここで説明されて

答えて

20

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(); 
+0

ありがとうございました。私の理解が正しい場合、モデルは新しく作成されたフィールドを持ち、すべてのRealm.getInstance(これ)はRealm.getInstance(config <上のように設定されます) – User

+2

です。 'Realm.getInstance(Context)'の代わりに 'Realm.getDefaultInstance()'や 'Realm.getInstance(RealmConfiguration)'を使うべきです。 –

+0

今日、私は "io.realm.exceptions.RealmMigrationNeededException"を取得しようとしました:フィールド 'isSessionRecordingUploading'は、既存のレルムファイルでヌル値をサポートしています。 'isSessionRecordingUploading'フィールドに対応するボックスタイプを使用するか、io.realm.internal.Table .convertColumnToNotNullable() " RealmMigrationクラスを少し修正し、RealオブジェクトのフィールドにnotNullアノテーションを追加しました。しかし、私はまだこの問題を克服できませんでした。私はQを更新しました。 – User

0

これは私がインポートしてきたヘルパークラスです。 realmデータベースを自分のアプリケーションにコピーします。私の場合、私はちょうどあなたがする必要がある

(複数の.realmファイルをインポートする必要がある場合)を使用すると、複数の領域の構成を有している場合
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{ 
} 
} 

AndroidアプリでiOSアプリケーションから作成されたデシベルを読む必要がありますRealmModuleクラスを作成し、RealmConfiguration.Builderで.modules()オプションを使用します。

デフォルトでrealm RealmObjectを拡張するすべてのモデルに対して.realmがテーブルを持っているかどうかを確認し、複数の.realmがある場合は、それぞれがクラスの一部を持ちますそのうちの)。

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

realmが「このクラスはこのスキーマに見つかりませんでした」のような奇妙な例外を与えている場合、通常は実際の問題を暗示できる別のエラーが表示されます。ランダムエラー。

+0

は['RealmConfiguration.assetFile()'](https://realm.io/docs/java/latest/api/io/realm/RealmConfiguration.Builder.html#assetFile-java.lang.String-)も主流ですか?また、「ランダムエラー」はありません。Instant Runを無効にする必要があります。 – EpicPandaForce

+0

こんにちは、私は他のユーザーを助けることを試みています。 sugestionsで自分のコードを編集しても構いません。そして、私はInstant Runを無効にしました。ファイルやテーブルが存在することを確信しても、 "このテーブル/クラスは存在しません"のようなランダムなエラーが発生しました。 – sagits

+0

私はRealmに既にassetFile()があると言っているので、手動でコピーを書く必要はありません:P – EpicPandaForce

関連する問題