Help us understand the problem. What is going on with this article?

FragmentにRealmObjectを渡すための手順と、Parcelerの使い方

More than 1 year has passed since last update.

はじめに

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"));

以上!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away