我在我的项目中使用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
}
问题只是我有一大堆需要转换的不同类型的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
}
无法正常工作,导致Android Studio出现编译错误,告诉我错误:类型转换器必须公开
任何人都知道如何为我的Room TypeConverter使用泛型?
答案 0 :(得分:0)
我刚试过这个,似乎为你要找的东西做了基础。由您来调整功能以满足您的需求,但这应该让您前进: 参考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
}
答案 1 :(得分:0)
我有同样的问题。仅用于转换listToString的部分解决方案
@TypeConverter
@JvmStatic
fun listToString(list: List<*>?): String? = list.let {
val gson = GsonBuilder().serializeNulls().create()
gson.toJson(it)
}
答案 2 :(得分:0)
我试图使用标记器接口将类转换为标记器,反之亦然,但这没有用。我尝试了大多数Java扩展的Object
类,但是没有用。我认为答案是您不能在房间类型转换器中使用Generic。
答案 3 :(得分:0)
这样的东西对模板不起作用吗?
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
}
或者从当前的例子来看,如果我这样做了
@TypeConverter
fun <T> mapStringToList(inputString: String): List<T> {
val array = inputString
.split(strSeparator.toRegex())
.dropLastWhile { it.isEmpty() }
.toTypedArray()
val result = mutableListOf<T>()
val gson = Gson()
// ? ----
val type = object : TypeToken<List<T>>() {}.type
// ----
return array.fold(result) { acc, item ->
acc.add(gson.fromJson(item, type))
acc
}
}
答案 4 :(得分:-1)
好吧,基本上类型转换器的主要思想是数据库不能将对象作为参数读取。因此,您必须采用两种方法,第一种是使用db内部的join关系手动进行操作,也可以使用type转换器。 类型转换器如何工作? 它很简单,只需将您的对象转换为JSON String并将其保存为字符串。 在您遇到的问题中,您必须在实体之前添加注释
private class YourDTO(
@TypeConverters(DateConverter.class)
Date date
在DateConverter类中
@TypeConverter
public static Long toTimestamp(Date date) {
return date == null ? null : date.getTime();
}