はじめに
Realmを利用していて、Fragmentに渡したいなと思ったときに、Serializable実装してBundleにputSerializableしたらonPauseで強制終了してしまった。
そもそも渡せるのかということを含め調べて実装方法が分かったのでメモする。
解決だけしたい人は結論を見てくださいな。
やりたいこと
public static Fragment newInstance(SampleRealmObject realmObject) {
Bundle args = new Bundle();
args.putParcelable("key", realmObject);
...
}
道のり
まずはじめに、RealmObjectは特に複雑なことをやっているわけではないモデルクラスだったので、Serializable実装すればputSerializableできるのではと考え実装してみた。
すると、うまく渡せてアプリが動いたのだが・・・、
画面を消したり、ホーム画面に戻ったときに、
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = io.realm.SampleRealmObjectRealmProxy)
Caused by: java.io.NotSerializableException: io.realm.SampleRealmObjectRealmProxy$SapmleRealmObjectColumnInfo
と言われてしまった。
Proxyが絡むからSerializeは無理なのか・・・と思い、Parcelableなら行けるかと思い調べてみると
この記事を発見https://realm.io/jp/docs/java/latest/#parceler
リンク先が載っているにも関わらず、それを読みもせず愚直にRealmに記載されていた記述を追加
compile "org.parceler:parceler-api:1.0.3"
apt "org.parceler:parceler:1.0.3"
うまく動かないので調べていたらこちらの記事を発見http://qiita.com/kazhida/items/affe4488078a2e625d33#%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA
記述を追加してビルドすると、通ったので一件落着。
と思いきや、警告が表示された。
Warning:Using incompatible plugins for the annotation processing: android-apt. This may result in an unexpected behavior.
android-aptは良くなくて、もしかしたら期待外の動作をするかもよ。と。
それでググってみると下記の記事が見つかる。
https://stackoverflow.com/questions/42632662/android-studio-warning-using-incompatible-plugins-for-the-annotation-processing
ベストアンサーを読むと、ButterKnifeの例が出ていて
『apply plugin: 'com.neenbedankt.android-apt'を消しましょう』と書いてある
試しに消して実行してみると、annotationProcessorがない的なエラーが。
見比べると、自分のコードにはannotationProcessorがなかったので、これはParcelerにもあるのでは?とライブラリのページに行ってみて検索で引っ掛けるとgradleのところに書いてあった。
それを記述すると警告無しで完了。
Realmの記載を鵜呑みにするべきではなかったというお話。
(もしかしたら何か良い方法があるのかもしれないが)
結論
1.アプリのbuild.gradleに記載を追加
compile 'org.parceler:parceler-api:1.1.9'
annotationProcessor 'org.parceler:parceler:1.1.9'
詳しくはこちらhttps://github.com/johncarl81/parceler
2.RealmObjectに@Parcelを追加
@Parcel(implementations = SampleRealmObjectRealmProxy.class,
value = Parcel.Serialization.BEAN,
analyze = SampleRealmObject.class)
public class SampleRealmObject extends RealmObject {
...
}
詳しくはこちらhttps://realm.io/jp/docs/java/latest/#parceler
3.putParcelableするときにParcels.wrapを加える
public static Fragment newInstance(SampleRealmObject realmObject) {
Bundle args = new Bundle();
args.putParcelable("key", Parcels.wrap(realmObject));
...
}
// 復元するときはunwrap
SampleRealmObject realmObject = Parcels.upwrap(getArguments().getParcelable("key"));
以上!