Ошибка комнаты в Android: TypeConverter не распознается для списка перечислений

Библиотека Room не распознает TypeConverter я создал для List перечислений. Однако, когда я изменяю это на ArrayList перечислений, он отлично работает. Кто-нибудь знает, почему и что я могу сделать, чтобы эта работа со List ? (Использование List в Kotlin проще, и я действительно не хочу конвертировать назад и вперед в ArrayList именно из-за этого).

Вот мой код:

Моя модель:

 @Entity data class Example(@PrimaryKey val id: String?, val name: String, var days: List<DayOfWeek>?) 

DayOfWeek – это перечисление:

 enum class DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; val value: Int get() = ordinal + 1 companion object { private val ENUMS = DayOfWeek.values() fun of(dayOfWeek: Int): DayOfWeek { if (dayOfWeek < 1 || dayOfWeek > 7) { throw RuntimeException("Invalid value for DayOfWeek: " + dayOfWeek) } return ENUMS[dayOfWeek - 1] } } } 

Мой TypeConverter :

 private const val SEPARATOR = "," class DayOfWeekConverter { @TypeConverter fun daysOfWeekToString(daysOfWeek: List<DayOfWeek>?): String? { return daysOfWeek?.map { it.value }?.joinToString(separator = SEPARATOR) } @TypeConverter fun stringToDaysOfWeek(daysOfWeek: String?): List<DayOfWeek>? { return daysOfWeek?.split(SEPARATOR)?.map { DayOfWeek.of(it.toInt()) } } } 

И я установил его в своем классе DB следующим образом:

 @Database(entities = arrayOf(Example::class), version = 1) @TypeConverters(DayOfWeekConverter::class) abstract class AppDatabase : RoomDatabase() { abstract fun exampleDao(): ExampleDao } 

Мой DAO выглядит так:

 @Dao interface ExampleDao { @Query("SELECT * FROM example") fun getAll(): LiveData<List<Example>> @Insert(onConflict = REPLACE) fun save(examples: List<Example>) } 

Ошибка, которую я получаю с этим кодом:

 error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. e: e: private java.util.List<? extends com.example.DayOfWeek> days; 

Как я уже сказал выше, если я изменил свойство days на ArrayList<DayOfWeek> (и внеся изменения в ArrayList в DayOfWeekConverter ), тогда все будет хорошо. Если кто-нибудь может помочь мне понять это и рассказать мне, как я могу использовать List здесь, это было бы очень полезно, это сводит меня с ума: /.

По какой-то причине Room не нравится Kotlin List , но когда я заменил List with MutableList он начал работать:

 @Entity data class Example(@PrimaryKey val id: String, val name: String, var days: MutableList<DayOfWeek>?) class DayOfWeekConverter { companion object { @TypeConverter @JvmStatic fun daysOfWeekToString(daysOfWeek: MutableList<DayOfWeek>?): String? = daysOfWeek?.map { it.value }?.joinToString(separator = SEPARATOR) @TypeConverter @JvmStatic fun stringToDaysOfWeek(daysOfWeek: String?): MutableList<DayOfWeek>? = daysOfWeek?.split(SEPARATOR)?.map { DayOfWeek.of(it.toInt()) }?.toMutableList() } } 

Это не идеальное решение, но надеюсь, что вы сможете больше узнать об этом.

Также вам нужно изменить @PrimaryKey чтобы он был недействительным

У нас нет возможности хранить и получать перечисление List без списка массивов. Номер не поддерживает его. Но если вы хотите избежать использования списка массивов, вы можете создать объект ListDayOfWeek со списком – это атрибут. Я попробовал, и все в порядке. Если вам нужен код, ответьте здесь. Я отправлю его.

Вы не должны хранить его в вашей базе данных. Лучше постройте что-то подобное и сохраните его как int:

 enum class DaysOfWeek(var bitValue: Int) { Monday(64), Tuesday(32), Wednesday(16), Thursday(8), Friday(4), Saturday(2), Sunday(1); } 

Наконец, ваша утилита выполняет функцию преобразования из / в перечисление.

 fun daysToBitValue(days: EnumSet<DaysOfWeek>): Int { var daysBitValue = 0 for (`val` in days) daysBitValue += `val`.bitValue return daysBitValue } private fun fromBitValues(origBitMask: Int): EnumSet<DaysOfWeek> { val ret_val = EnumSet.noneOf(DaysOfWeek::class.java) var bitMask = origBitMask for (`val` in DaysOfWeek.values()) { if (`val`.bitValue and bitMask == `val`.bitValue) { bitMask = bitMask and `val`.bitValue.inv() ret_val.add(`val`) } } if (bitMask != 0) { throw IllegalArgumentException(String.format(Locale.getDefault(), "Bit mask value 0x%X(%d) has unsupported bits 0x%X. Extracted values: %s", origBitMask, origBitMask, bitMask, ret_val)) } return ret_val } 

Теперь вы можете либо сохранить int и получить будние дни позже:

 @Entity data class Example(@PrimaryKey val id: String?, val name: String, var days: Int = 0) 

или вы используете перечисление и пишите для этого подходящий typeconverter.

 @Entity data class Example(@PrimaryKey val id: String?, val name: String, var days: EnumSet<DaysOfWeek>?) class DayOfWeekConverter { @TypeConverter fun daysOfWeekToString(daysOfWeek: EnumSet<DayOfWeek>?) = daysOfWeek?.let{ YourUtilities.daysToBitValue(it) } @TypeConverter fun intToDaysOfWeek(daysOfWeek: Int?) = daysOfWeek?.let { YourUtilities.fromBitValues(it) } } 

Вы можете прокручивать перечисление и получать все дни, используя

 for (aDaysOfWeekEnumSet in daysOfWeekEnumSet) info{ "day = ${aDaysOfWeekEnumSet.name"} 

Код не проверен, потому что im не на моем компьютере, но это должно показать концепцию, которая работает лучше, чем хранение перечисления (которое является просто псевдонимом для предопределенного значения!)

Intereting Posts
Kotlin запускается в случае сбоя Android Studio «Не удалось синхронизировать Gradle: время ожидания подключения: подключитесь к журналу IDE для получения дополнительной информации (Help | Show Log)» Почему добавление представления в мой макет меняет ширину всего макета? Android Kotlin создает реализацию класса Parcelable дает ошибку в «переопределении» метода writeToParcel Объем модификатора внутренней видимости в Котлине UNINITIALIZED_VARIABLE Переменная _longPressed должна быть инициализирована Чтение и обработка HOCON в Котлине Котлинские аннотации о делегированных свойствах Равенство идентичности для аргументов типов Int и Int устарело Переменная «runnable» должна быть инициализирована Kotlin, Java, multidex, Dagger 2, Butterknife and Realm: transformClassesWithJarMergingForDebug: дублирующаяся запись: org / jetbrains / annotations / NotNull.class Добавление списка подтипов в список супертипов в Котлине Firebase Android Авто Войти Комната: получение ошибки при использовании @Transaction Kotlin – Идиоматический способ удаления повторяющихся строк из массива? Стандартное отклонение Kotlin с дженериками