久しぶりにRealm Javaを使ったアプリをアップデートすることになり色々と手を入れている最中なのですが、使用しているライブラリのひとつの「Realm Java」も古いバージョンのものを使っていたのでこの機会にアップデートさせようとしました。
この記事ではv0.80.3からv0.90.0へのアップデートで起こった問題について記載します。
ベースのコードはv0.80.3以前のものなので v0.80.3 時点で非推奨になっていたコードもあるかもしれません。…と先に書いておきます。
Realm Java 0.90.0へアップデートする
まずRealm Javaの追加の方法から変更になっていました。アップデートに際してapp/build.gradle
の数字部分を変更するだけではダメでした。
dependencies { // ... compile 'io.realm:realm-android:0.80.3' // ... }
↓
app/build.gradle
のdependenciesから削除して、ファイルの先頭あたりに追加する。
apply plugin: 'com.android.application' apply plugin: 'realm-android'
build.gradle
のbuildscript.dependenciesにclasspathを追加する。
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0' classpath 'io.realm:realm-gradle-plugin:0.90.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
これでRaelm Javaの新しいバージョンをインストールすることができるようになりました。
ビルドエラーの対策
次に、アップデート方法の変更でわかるようにv0.80.3からv0.90.0へは少し時間があいていたようで、従来のコードでRealmビルドエラーが発生するようになってしまっていたようです。
allObjectsSortedがなくなっていた
allObjectsSorted(Class,String,bool)
自体が消えていてビルドが通らなくなっていました。
昔から存在していたのか調べていませんが、allObjectsSorted(Class,String,Sort)
が追加されていたようです。しかし、切り替える以前に非推奨になったいたようです。
results = realm.allObjectsSorted(Favorite.class, "createAt", true);
↓
results = realm.where(Favorite.class) .findAllSorted("createAt", Sort.ASCENDING);
RealmChangeListener.onChange()が引数付きに変更されていた
Realmのデータベースが変更されるとアプリ側で通知を受け取るができる仕組みがあります。RealmChangeListener.onChange()
に引数が追加されていました。
@Override public void onChange() { adapter.notifyDataSetChanged(); }
↓
@Override public void onChange(Object element) { adapter.notifyDataSetChanged(); }
データベースにデータが追加されていない
上記のビルドエラーを修正してアプリの起動自体はできるようになりました。
開発中のアプリではJSONファイルを読み込んでRealmのデータベースへデータを追加します。しかし一部のデータがデータベースに追加されていません。
Realm.createAllFromJsonメソッドでJSONを読み込んだ時に失敗しているようで、ログを見たところ例外が発生しているようでした。
java.lang.IllegalArgumentException: Trying to set non-nullable field price to null.
W/System.err: java.lang.IllegalArgumentException: Trying to set non-nullable field price to null. W/System.err: at io.realm.UserRealmProxy.createOrUpdateUsingJsonObject(UserRealmProxy.java:451)
Realm Java v0.83で導入されたこの変更の影響しているのかもしれません。
これを踏まえて修正しました。
public class User extends RealmObject { @PrimaryKey private int code; private int price; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
↓
public class User extends RealmObject { @PrimaryKey private int code; private Integer price; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
関係ありそうな部分をブログ用にピックアップしてきただけなので実際のコードとは異なるのですが、Userクラスにpriceフィールドがいてる……