RealmObject和Parcelable

时间:2014-12-01 15:05:38

标签: java android sqlite parcelable realm

我是Realm for Android的新手,所以我不确定我是否正确接近这个问题。我有一个看起来像这样的课:

public class Entry extends RealmObject implements Parcelable {
    ...
}

问题是Parcelable接口包含describeContents() writeToParcel()等方法,而RealmObjects不应该包含getter和setter以外的方法:

Error:(81, 17) error: Only getters and setters should be defined in model classes

所以我的问题是:我如何让这两个一起工作?有没有比创建一个单独的类更好的方法(可能像RealmEntry)?这样做会导致大量重复的代码......

4 个答案:

答案 0 :(得分:9)

2016年5月更新:除非您已使用Parceler,否则此答案已过时。 @Henrique de Sousa的解决方案要好得多。


实际上,有一种解决方法。如果您愿意使用第三方库(Parceler)进行Parcelable生成,则可以获得所需的结果。有关方便,请参阅下面引用的my answer to this other question

  

使用Parceler v0.2.16,您可以执行此操作:

     
@RealmClass      // required if using JDK 1.6 (unrelated to Parceler issue)
@Parcel(value = Parcel.Serialization.BEAN, analyze = { Feed.class })
public class Feed extends RealmObject {
    // ...
}
     

然后,在任何地方使用Parcels.wrap(Feed.class, feed)代替Parcels.wrap(feed),否则您的应用会因org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for io.realm.FeedRealmProxy而崩溃。

答案 1 :(得分:4)

现在有一个不同的解决方法:只需实现RealmModel界面,而不是从RealmObject扩展:

@RealmClass
public class User implements RealmModel {

}

您可以在Realm Documentation

中找到更多信息

答案 2 :(得分:0)

目前无法在RealmObjects上实现Parcelable。 一种解决方案是使用两个领域文件:默认文件作为对象库,一个专门用于临时保存轮换等。

答案 3 :(得分:0)

Parceler 在 android x 中不起作用。 你可以用这个:

class ExParcelable @JvmOverloads constructor(data: Any? = null) : Parcelable {
    var cls: String? = null
    var json: String? = null

    init {
        if (data is Parcel) {
            cls = data.readString()
            json = data.readString()
        } else {
            cls = data?.let { it::class.java }?.canonicalName
            json = Gson().toJson(data)
        }
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(cls)
        parcel.writeString(json)
    }

    override fun describeContents(): Int {
        return 0
    }

    fun value(): Any? {
        return Gson().fromJson(this.json, Class.forName(this.cls))
    }

    companion object CREATOR : Creator<ExParcelable> {
        override fun createFromParcel(parcel: Parcel): ExParcelable {
            return ExParcelable(parcel)
        }

        override fun newArray(size: Int): Array<ExParcelable?> {
            return arrayOfNulls(size)
        }
    }
}

和:

inline fun <reified T : Any?> Intent.extra(key: String): T? {
    var value = extras?.get(key)
    if (value is ExParcelable) {
        value = value.value()
    } else if (T::class == Uri::class) {
        if (value is String) {
            value = value.toUri()
        }
    } else if (T::class == String::class) {
        if (value is Uri) {
            value = value.toString()
        }
    }
    return value as T?
}

inline fun <reified T : Any?> Intent.extra(key: String, value: T?) {
    when (value) {
        null -> {
            // no op
        }
        is Uri -> putExtra(key, value.toString())
        is Boolean -> putExtra(key, value)
        is BooleanArray -> putExtra(key, value)
        is Byte -> putExtra(key, value)
        is ByteArray -> putExtra(key, value)
        is Char -> putExtra(key, value)
        is CharArray -> putExtra(key, value)
        is Short -> putExtra(key, value)
        is ShortArray -> putExtra(key, value)
        is Int -> putExtra(key, value)
        is IntArray -> putExtra(key, value)
        is Long -> putExtra(key, value)
        is LongArray -> putExtra(key, value)
        is Float -> putExtra(key, value)
        is FloatArray -> putExtra(key, value)
        is Double -> putExtra(key, value)
        is DoubleArray -> putExtra(key, value)
        is Date -> putExtra(key, value)
        is Bundle -> putExtra(key, value)
        is Parcelable -> putExtra(key, value)
        is Serializable -> putExtra(key, value)
        is RealmObject -> putExtra(key, ExParcelable(value.get()))
        else -> putExtra(key, ExParcelable(value))
    }
}

并像这样使用它:

new Intent().apply{
    extra("test", realmObject)
}

和:

intent.extra("test")