我是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
)?这样做会导致大量重复的代码......
答案 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")