library Project で使う Realm 3.1.0
はじめに
祝3.1.0 ですね〜。全然新機能は使えてないのですが<汗
またまた今回も zaki さんにRealmのSlackで不具合解析の相談をさせていただきました。
何時も感謝です〜><
一応念のため、備忘録として残しておこうかと*1
動作環境
状況的な話
下記のエラーがでて、copyOrUpdateRealm でエラーが出て保存されなくてハマってた。
Realm RealmObject is not part of the schema for this Realm https://github.com/realm/realm-java/issues/3139
みたいな奴・・・・。まあ自分が使ってたのは RealmModelの方でしたが・・・
何故か OS6端末では動く/OS4、5では動かない という謎の状態・・。
一応アプリ消し手入れ直したりとかしてたんですけどね・・・
で zaki さんに相談したところ
APT変換で生成される*2自動生成コードのクラス判定分岐 が正常に生成されていないのでは?
とのお話でした
その時に、createOrUpdateAllFromJson の存在を教えてもらったんですけど、使ったことないなー(遠い目
createOrUpdateAllFromJson って主キーとかってどうなるんだろう? / “android - realm - update object with method createOr…” https://t.co/AcVAy28TRs #realm #java
— close_yutori (@kimukou2628) April 6, 2017
githubでちょっと検索かけてみたけど、あんまり使ってるコードが見なかったかも・・
どのOSでも確実に動いたパターン
RealmInfoXXX は RealmModel を implements したクラス
@RealmClass public class RealmInfoA implements RealmModel
Library Projectのソース同梱タイプ
MainP |---RealmInfoA LibP |---RealmInfoB |---RealmInfoC |---RealmInfoD
- MainP/build.gradle
dependencies{
compile project(':libP')
}
OS6でしか動かなかったパターン
LibPを make module で LibP.aar にしたパターン *3
MainP |---RealmInfoA LibP LibP.aar |---RealmInfoB |---RealmInfoC |---RealmInfoD
ASでlocal.jar を import するパターンですね・・
- libP/build.gradle
configurations.maybeCreate("default") artifacts.add("default", file('LibP.aar'))
- MainP/build.gradle は変更なし
で何が悪かったのか?
LibP.aar にして固めてしまうと RealmInfoB とかが RealmPlugin の APT変換対象にならない
でどう解決するのか?
Sharing schemas を使う
LibP側
上記のページを参考にして下記のクラスを作ると
- APT変換したコードが静的クラスとして生成
- aarのclass.jar に io.realmパッケージ追加+RealmModelの変換済みのクラスが同梱される
- 勿論staticクラスでもOK
@RealmModule(library = true, allClasses = true) public static class MyLibraryModule { }
- でコレをmoduleとして指定すると、クラス判定の条件分岐が増える
- 正常にRealmModel/RealmObject 判定ができて正常実行できるようになる
MainP側
勿論LibP側において、MainPで利用する形でもOK
ただ setDefaultRealmConfiguration あたりはどうしても、本体側のApplication に記載する必要があるしな〜
変更前
.moduleは、変更前だと下記と同じ状況のようです
.modules(Realm.getDefaultModule())
- RealmUtils.java
public class RealmUtils { private static RealmConfiguration getRealmConfiguration(@NonNull String filename, int schemaVersion, RealmMigration migration) { RealmConfiguration.Builder builder = new RealmConfiguration.Builder()//context) .name(filename) .deleteRealmIfMigrationNeeded() .schemaVersion(schemaVersion); if(migration != null){ builder.migration(migration); } return builder.build(); } }
変更後
- RealmUtils.java
public class RealmUtils { //[TODO] aarのclass.jar に io.realmパッケージ追加+RealmModelの変換済みのクラスが同梱される @RealmModule(library = true, allClasses = true) public static class MyLibraryModule { } private static RealmConfiguration getRealmConfiguration(@NonNull String filename, int schemaVersion, RealmMigration migration) { RealmConfiguration.Builder builder = new RealmConfiguration.Builder()//context) .name(filename) .modules(Realm.getDefaultModule(), new MyLibraryModule()) //★ ココを追加 .deleteRealmIfMigrationNeeded() .schemaVersion(schemaVersion); if(migration != null){ builder.migration(migration); } return builder.build(); } }
OS6で何で動いたのか? あたりの調査
うーん。自動生成コードを見る限り動くはずがないんですよね・・・
RealmInfoAの分岐しか作られていないので。
何度も下記のオペレーションをしていたのですが・・・。
- アプリ消去
- データ消去
- 端末再起動
ただ開発の常用端末なので、InstantRunのゴミが上記のオペレーションで消しきれていないのではないか 疑惑が有り。*4
だとすると、InstantRun 怖w って結論になってしまうのかなー
- ただ AS2.4pの挙動見てると、
- DebugモードはInstantRun必須*5
とかなりそうなので、それはそれでバギーな状況になりそう・・*6