web-dev-qa-db-fra.com

Android Erreur de pièce: TypeConverter non reconnu pour la liste des énumérations

La bibliothèque Room ne reconnaît pas un TypeConverter que j'ai créé pour un List d'énumérations. Cependant, lorsque je change cela en ArrayList d'énumérations, cela fonctionne très bien. Tout le monde sait pourquoi et que puis-je faire pour que cela fonctionne avec List? (Utiliser List dans Kotlin est plus facile et je ne veux vraiment pas convertir en avant et en arrière en ArrayList juste à cause de cela).

Voici mon code:

Mon modele:

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

DayOfWeek est une énumération:

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]
        }

    }

}

Mon 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()) }
    }

}

Et je l'ai mis dans ma classe DB comme ceci:

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

    abstract fun exampleDao(): ExampleDao

}

Mon DAO ressemble à ceci:

@Dao
interface ExampleDao {

    @Query("SELECT * FROM example")
    fun getAll(): LiveData<List<Example>>

    @Insert(onConflict = REPLACE)
    fun save(examples: List<Example>)

}

L'erreur que j'obtiens avec ce code est:

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;

Comme je l'ai dit ci-dessus, si je change la propriété days en ArrayList<DayOfWeek> (et apportez les modifications à ArrayList dans DayOfWeekConverter) alors tout fonctionne correctement. Si quelqu'un peut m'aider à comprendre cela et me dire comment je peux utiliser List ici, ce serait d'une grande aide, cela me rend fou: /.

13
Franco

Pour une raison quelconque, Room n'aime pas Kotlin List, mais quand j'ai remplacé List par MutableList, cela a commencé à fonctionner:

@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()
    }
}

Ce n'est pas une solution parfaite, mais j'espère que vous pourrez en savoir plus avec cela.

Vous devez également modifier @PrimaryKey pour ne pas être annulable

13
Tomek Polański

La signature complète de List dans Kotlin est List<out E> (List<? extend E> en Java), cela n'a aucun sens de convertir ce type générique. En d'autres termes, Room ne sait pas si l'entrée est un DayOfWeek ou sa sous-classe.

Quant à ArrayList et MutableList, leur signature complète est ArrayList<E> et MutableList<E> en conséquence, le type d'entrée est fixe et donc Room sait comment le convertir.

2
jaychang0917