如何从自定义列表在 Room 中制作 TypeConverter? [英] How to make a TypeConverter in Room from a custom list?

查看:39
本文介绍了如何从自定义列表在 Room 中制作 TypeConverter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个 TypeConverter,但出现错误

I have made a TypeConverter but I get an error

无法为类创建转换器.models.lastanime.EpisodesEntityfor 方法 EpisodesApi.getEpisodes

Unable to create converter for class .models.lastanime.EpisodesEntityfor method EpisodesApi.getEpisodes

我无法理解如何制作TypeConverter,我已经这样做了,我知道实现是正确的,因为我在编译中没有遇到问题,但是由于出现错误,数据没有加载,而且好像没有保存在房间数据库中

I can't finish understanding how to make the TypeConverter, I have done this, I know that the implementation is placed correctly since I have not had problems in the compilation, but the data does not load since I get an error, and it seems that it is not saved in the room database

类型转换器

class ListStringConverter {

    @TypeConverter
    fun fromString(value: String?): List<ServerEntity> {
        val listType = object :
            TypeToken<List<ServerEntity?>?>() {}.type
        return Gson()
            .fromJson<List<ServerEntity>>(value, listType)
    }

    @TypeConverter
    fun listToString(list: List<ServerEntity?>?): String {
        val gson = Gson()
        return gson.toJson(list)
    }

}

模型集实体

data class EpisodesEntity(
@SerializedName("episodes")
val episodes: List<EpisodeEntity>

)

模型剧集实体

@Entity
data class EpisodeEntity(

    @PrimaryKey(autoGenerate = true)
    val id: Int,

    @SerializedName("poster")
    @ColumnInfo(name = "episode")
    val episode: Int?,

    @SerializedName("poster")
    @ColumnInfo(name = "poster")
    val poster: String?,

    @SerializedName("servers")
    @ColumnInfo(name = "servers")
    val servers: List<ServerEntity>?,

    @SerializedName("title")
    @ColumnInfo(name = "title")
    val title: String?

)

除了所有模型之外,服务器列表也让我无法将其插入房间

In addition to all the model, the list of Servers is what gives me trouble inserting it in room

@SerializedName("servers")
    @ColumnInfo(name = "servers")
    val servers: List<ServerEntity>?,

API 存储库

interface LastEpisodesRepository {

fun lastEpisodes(): Flow<Either<Failure, List<Episode>>>

class Network(
    private val networkHandler: NetworkHandler,
    private val service: LastEpisodesService,
    private val local: EpisodeLocal
) : LastEpisodesRepository {

    val preferences by lazy { SharedPrefsHelpers() }

    override fun lastEpisodes(): Flow<Either<Failure, List<Episode>>> =
        flow {

            val days = local.getEpisodes()
            val time = preferences.getLong(LocalShared.LastAnimes.lastepisodes, 0L)

            if (days.isNullOrEmpty() || time == 0L || isFetchCurrentNeeded(time)) {
                emit(getRemoteDay())
            } else {
                emit(Either.Right(local.getEpisodes().map { it.toEpisode() }))
            }
        }.catch {
            emit(Either.Left(Failure.CustomError(ServiceKOs.DATABASE_ACCESS_ERROR, "DB Error")))
        }.flowOn(Dispatchers.IO)


    private fun getRemoteEpisode(): Either<Failure, List<Episode>> =
        when (networkHandler.isConnected) {
            true -> request(
                service.getEpisodes(),
                { episodeEntity ->

                    val episodeList: List<EpisodeEntity> = episodeEntity.episodes

                    preferences.saveLong(LocalShared.LastAnimes.lastepisodes, Date().time)

                    addAllEpisodes(episodeList)
                    episodeList.map { it.toEpisode() }

                },
                EpisodesEntity(emptyList())
            )
            false, null -> Either.Left(Failure.NetworkConnection())
        }

    private fun addAllEpisodes(episodes: List<EpisodeEntity>) {
        for (episode in episodes) {
            local.addEpisodes(episode)
        }
    }

}

Room 是从局部变量进行的调用,应用程序检查是否有下载的数据,如果没有,则调用服务,返回数据,同时将其保存在 Room 数据库中.

Room are the calls that are made from the local variable, the application checks if there is downloaded data and if there is not, it calls the service, returns the data and at the same time saves it in the Room database.

推荐答案

经过几天仔细研究 Room 的高级插入,我发现了如何为特定的自定义对象制作 TypeConverter, 在我的情况下 ServersEntity

After several days carefully studying more about the advanced inserts of Room, I have discovered how to make the TypeConverter for a specific custom object, In my case ServersEntity

@TypeConverter
fun stringToListServer(data: String?): List<ServerEntity?>? {
    if (data == null) {
        return Collections.emptyList()
    }
    val listType: Type = object :
        TypeToken<List<ServerEntity?>?>() {}.type
    return gson.fromJson<List<ServerEntity?>>(data, listType)
}

@TypeConverter
fun listServerToString(someObjects: List<ServerEntity?>?): String? {
    return gson.toJson(someObjects)
}

另一方面,要转换字符串列表,只需按如下方式完成

On the other hand to convert the String lists, it would simply be done as follows

@TypeConverter
fun fromString(value: String?): List<String> {
    val listType = object :
        TypeToken<ArrayList<String?>?>() {}.type
    return Gson().fromJson(value, listType)
}

@TypeConverter
fun fromList(list: List<String?>?): String {
    val gson = Gson()
    return gson.toJson(list)
}

这篇关于如何从自定义列表在 Room 中制作 TypeConverter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆