android - 带有@Parcelize 注解的RealmList

标签 android kotlin realm parcelable parceler

我正在尝试使用新的 @Parcelize Kotlin 1.1.4 中添加的注解带有包含 RealmList 属性的 Realm 对象。

@Parcelize
@RealmClass
open class Garage(
        var name: String? = null,
        var cars: RealmList<Car> = RealmList()
) : Parcelable, RealmModel

作为RealmList注释不支持并假设 @Parcelize是否有专门避免创建方法的方法支持RealmList 的解决方案是什么? ?

提前致谢

最佳答案

编辑:

使用 Type Parcelers 和 @WriteWith 的力量注释,可以创建一个可以为您处理这种情况的 RealmList 类型的 parceler:

使用以下代码:

fun <T> Parcel.readRealmList(clazz: Class<T>): RealmList<T>?
    where T : RealmModel,
          T : Parcelable = when {
    readInt() > 0 -> RealmList<T>().also { list ->
        repeat(readInt()) {
            list.add(readParcelable(clazz.classLoader))
        }
    }
    else -> null
}

fun <T> Parcel.writeRealmList(realmList: RealmList<T>?, clazz: Class<T>)
    where T : RealmModel,
          T : Parcelable {
    writeInt(when {
        realmList == null -> 0
        else -> 1
    })
    if (realmList != null) {
        writeInt(realmList.size)
        for (t in realmList) {
            writeParcelable(t, 0)
        }
    }
}

你可以这样定义一个接口(interface):

interface RealmListParceler<T>: Parceler<RealmList<T>?> where T: RealmModel, T: Parcelable {
    override fun create(parcel: Parcel): RealmList<T>? = parcel.readRealmList(clazz)

    override fun RealmList<T>?.write(parcel: Parcel, flags: Int) {
        parcel.writeRealmList(this, clazz)
    }

    val clazz : Class<T>
}

您需要在何处为 RealmList<Car> 创建特定的打包程序像这样:

object CarRealmListParceler: RealmListParceler<Car> {
    override val clazz: Class<Car>
        get() = Car::class.java
}

但是,现在您可以执行以下操作:

@Parcelize
@RealmClass
open class Garage(
        var name: String? = null,
        var cars: @WriteWith<CarRealmListParceler> RealmList<Car> = RealmList()
) : Parcelable, RealmModel

@Parcelize
@RealmClass
open class Car(
    ..
): RealmModel, Parcelable {
    ...
}

这样您就不需要手动编写 Parceler 逻辑。



原始答案:

以下应该有效:

@Parcelize
open class Garage: RealmObject(), Parcelable {
    var name: String? = null
    var cars: RealmList<Car>? = null

    companion object : Parceler<Garage> {
        override fun Garage.write(parcel: Parcel, flags: Int) {
            parcel.writeNullableString(name)
            parcel.writeRealmList(cars)
        }

        override fun create(parcel: Parcel): Garage = Garage().apply {
            name = parcel.readNullableString()
            cars = parcel.readRealmList()
        }
    }
}

只要你还添加以下扩展函数:

inline fun <reified T> Parcel.writeRealmList(realmList: RealmList<T>?)
    where T : RealmModel,
          T : Parcelable {
    writeInt(when {
        realmList == null -> 0
        else -> 1
    })
    if (realmList != null) {
        writeInt(realmList.size)
        for (t in realmList) {
            writeParcelable(t, 0)
        }
    }
}

inline fun <reified T> Parcel.readRealmList(): RealmList<T>?
    where T : RealmModel,
          T : Parcelable = when {
    readInt() > 0 -> RealmList<T>().also { list ->
        repeat(readInt()) {
            list.add(readParcelable(T::class.java.classLoader))
        }
    }
    else -> null
}

还有

fun Parcel.writeNullableString(string: String?) {
    writeInt(when {
        string == null -> 0
        else -> 1
    })
    if (string != null) {
        writeString(string)
    }
}

fun Parcel.readNullableString(): String? = when {
    readInt() > 0 -> readString()
    else -> null
}

关于android - 带有@Parcelize 注解的RealmList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49455684/

相关文章:

android - 工具栏标题文字大小

android - 导航组件透明工具栏

kotlin - Kotlin中*操作的作用是什么?

swift - 对象、结果等是否保留它们的 Realm 实例?

android - 模拟器在启动动画等待 HOME ('android.process.acore' 时挂起)要启动

java - 如何从sqlite表中获取最后一个时间戳日期

android - 如何检查 Android 运行时权限/从 LibGdx 核心模块获取 Android 当前 Activity ?

ios - 使用 Realm 数据库中的日期快速设置 UserNotification

swift - 为什么我无法在 Realm 对象上设置属性?

android - 如何让一个应用适合不同的手机