房间类型地图转换器

时间:2018-08-18 21:57:17

标签: android android-room android-architecture-components android-jetpack

您将如何为Map编写TypeConverter?我的方法是由Moshi做到

class Converters() {

    val moshi = Moshi
            .Builder()
            .add(KotlinJsonAdapterFactory())
            .build()

    val mapOfStringsType = Types.newParameterizedType(Map::class.java, String::class.java, String::class.java)
    val mapOfStringsAdapter = moshi.adapter<Map<String, String>>(mapOfStringsType)


    @TypeConverter
    fun stringToMap(data: String): Map<String, String> {
        return mapOfStringsAdapter.fromJson(data).orEmpty()
    }

    @TypeConverter
    fun mapToString(map: Map<String, String>): String {
        return mapOfStringsAdapter.toJson(map)
    }
}

但是,它有气味,因为我无法通过Converters()构造函数注入Moshi。 而且,恐怕也不是最好的表现。

3 个答案:

答案 0 :(得分:3)

我通常将gson用作Room TypeConverters。它提供了适用于所有对象类型的简单实现:

public class StringMapConverter {
    @TypeConverter
    public static Map<String, String> fromString(String value) {
        Type mapType = new TypeToken<Map<String, String>>() {
        }.getType();
        return new Gson().fromJson(value, mapType);
    }

    @TypeConverter
    public static String fromStringMap(Map<String, String> map) {
        Gson gson = new Gson();
        return gson.toJson(map);
    }
}

答案 1 :(得分:0)

根据brian-acker的响应,在Kotlin中使用Moshi的类似TypeConverter类似于:

class Converters {

  private val mapAdapter =
      Moshi.Builder().add(SingleToArray.Adapter.FACTORY).build().adapter<Map<String, String>>(
          Map::class.java)

  @TypeConverter
  fun fromJson(aString: String?): Map<String, String>? =
      aString?.let { mapAdapter.fromJson(it) }

  @TypeConverter
  fun toJson(aMap: Map<String, Any>?): String? =
      aMap?.let { anyMapAdapter.toJson(it) }

}

答案 2 :(得分:0)

我为原始 Map 值提出了一个解决方案。例如 StringBooleanIntegerLong 等。在此处查看更多信息 https://kotlinlang.org/docs/basic-types.html

每次您想从 Room 数据库中获取项目时都创建一个 Gson 实例可能会很昂贵,在这种情况下,这是解决此问题的一种懒惰的方法。

如果您曾经见过转换字符串列表的解决方案,那么下面的示例应该是不言自明的。

不是将 Map 视为 Kotlin 对象,而是将其视为两个数组:键和值。我们的大帮手是 TreeMap,因为 Map.keys 返回未排序的 Set

@TypeConverter
fun fromStringMap(value: Map<String, String>): String {
    val sortedMap = TreeMap(value)
    return sortedMap.keys.joinToString(separator = ",").plus("<divider>")
        .plus(sortedMap.values.joinToString(separator = ","))
}

@TypeConverter
fun toStringMap(value: String): Map<String, String> {
    return value.split("<divider>").run {
        val keys = getOrNull(0)?.split(",")?.map { it }
        val values = getOrNull(1)?.split(",")?.map { it }

        val res = hashMapOf<String, String>()
        keys?.forEachIndexed { index, s ->
            res[s] = values?.getOrNull(index) ?: ""
        }
        res
    }
}

随意将分隔符 "" 替换为最适合您的用例的任何内容,这样您就不会遇到包含分隔符的值/键。