Android:如何为Kotlin中的所有对象列表创建类型转换器(for Room)

Rik*_*zen 13 database generics android kotlin android-room

我在我的项目中使用Room作为本地数据库解决方案.对于某个对象类型的每个列表,我都为项目添加了类型转换器,因此类型转换器看起来像这样:

@TypeConverter
fun convertListToString(video: List<VideoType>): String {

    val videoArray = arrayOfNulls<VideoType>(video.size)
    for (i in 0..video.size - 1) {
        videoArray[i] = video[i]
    }
    var str = ""
    val gson = Gson()
    for (i in videoArray.indices) {
        val jsonString = gson.toJson(videoArray[i])
        str = str + jsonString
        if (i < videoArray.size - 1) {
            str = str + strSeparator
        }
    }

    return str
}

@TypeConverter
fun convertStringToList(videoString: String): List<VideoType> {

    val videoArray = videoString.split(strSeparator.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
    val videos = ArrayList<VideoType>()
    val gson = Gson()
    for (i in 0 until videoArray.size - 1) {
        videos.add(gson.fromJson(videoArray[i], VideoType::class.java))
    }

    return videos
}
Run Code Online (Sandbox Code Playgroud)

问题只是我有一大堆需要转换的不同类型的List,所以目前我只是为每种类型复制这个代码.我想使用泛型,但到目前为止还没有弄清楚如何做到这一点.

例如使用类似的东西:

@TypeConverter
inline fun <reified T> convertStringToList(string: String): List<T> {
    val objectArray = string.split(strSeparator.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
    val objects = ArrayList<T>()
    val gson = Gson()
    for (i in 0 until objectArray.size - 1) {
        objects.add(gson.fromJson(objectArray[i], T::class.java))
    }
    return objects
}
Run Code Online (Sandbox Code Playgroud)

没有工作,导致Android Studio的编译错误给我一个错误告诉:类型转换器必须是公共的

任何人都知道如何为我的Room TypeConverter使用泛型?

Che*_*pta 6

这样的东西不适用于模板吗?

abstract class Converters<T> {

    @TypeConverter
    fun mapListToString(value: List<T>): String {
        val gson = Gson()
        val type = object : TypeToken<List<T>>() {}.type
        return gson.toJson(value, type)
    }

    @TypeConverter
    fun mapStringToList(value: String): List<T> {
        val gson = Gson()
        val type = object : TypeToken<List<T>>() {}.type
        return gson.fromJson(value, type)
    }
}

// create 
class UserConverter : Converters<User>()

// usage
@TypeConverters(UserConverter::class)
abstract class TestDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Run Code Online (Sandbox Code Playgroud)

或者从当前的例子来看,如果我这样做怎么办

abstract class Converters<T> {

    @TypeConverter
    fun mapListToString(value: List<T>): String {
        val gson = Gson()
        val type = object : TypeToken<List<T>>() {}.type
        return gson.toJson(value, type)
    }

    @TypeConverter
    fun mapStringToList(value: String): List<T> {
        val gson = Gson()
        val type = object : TypeToken<List<T>>() {}.type
        return gson.fromJson(value, type)
    }
}

// create 
class UserConverter : Converters<User>()

// usage
@TypeConverters(UserConverter::class)
abstract class TestDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Run Code Online (Sandbox Code Playgroud)


NSi*_*mon -2

我刚刚对此进行了测试,似乎为您所寻找的内容奠定了基础。您可以根据自己的需要调整该函数,但这应该能让您继续前进:参考https://kotlinlang.org/docs/reference/generics.html#generic-functions

fun test() {
        val list1 = listOf("1", "2")
        val list2 = listOf(1, 2, 3)

        list1.convertToString()
        list2.convertToString()
    }

    fun List<Any>.convertToString(): String {
        var result = ""
        val gson = Gson()
        for (i in 0.. size - 1) {
            result += gson.toJson(get(i), get(i).javaClass)
        }
        return result
    }
Run Code Online (Sandbox Code Playgroud)

  • 这可能可以将任何类型的列表转换为字符串,但它不能解决在 Room 中使用 typeConvertors 的问题。如果我在列表上使用扩展,我想转换为字符串(即使使用@typeConverter对其进行注释)“无法弄清楚如何将此字段保存到数据库中。” (4认同)