RealmObject AND Parcelable

Я новичок в Realm для Android, поэтому я не уверен, что подхожу к этому правильно. У меня есть класс, который выглядит так:

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

Проблема заключается в Parcelable интерфейс содержит такие методы, как describeContents()writeToParcel() и RealmObjects не должны иметь методов, отличных от методов получения и установки:

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

Итак, мой вопрос: как я могу заставить этих двух работать вместе? Есть ли лучший способ, чем создать отдельный класс (может быть, что-то вроде RealmEntry)? Это приведет к дублированию кода...

5 ответов

Решение

Теперь есть другой обходной путь: просто внедрите RealmModel интерфейс вместо расширения от RealmObject:

@RealmClass
public class User implements RealmModel {

}

Вы можете найти больше информации в Документации Царства.

ОБНОВЛЕНИЕ Май 2016: Это ответ устарел, если вы уже не используете Parceler. Решение Энрике де Соуза намного лучше.


На самом деле, есть обходной путь. Вы можете получить желаемый результат, если хотите использовать стороннюю библиотеку (Parceler) для Parcelable поколение. Смотрите мой ответ на этот другой вопрос, приведенный ниже для удобства.

С помощью 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,

В настоящее время невозможно реализовать Parcelable для RealmObjects. Одним из решений является использование двух файлов областей: по умолчанию один в качестве хранилища объектов и специализированный файл для временного сохранения для вращений и т. Д.

Решение с Kotlin:

import io.realm.com_labtest_di_model_EntryRealmProxy
import org.parceler.Parcel


@RealmClass
@Parcel(implementations = arrayOf(com_labtest_di_model_EntryRealmProxy::class),
    value = org.parceler.Parcel.Serialization.BEAN,
    analyze = arrayOf(Movie::class))
open class Entry() : RealmObject() {
...

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")
Другие вопросы по тегам