안드로이드 스튜디오 JetpackCompose - RoomDB Color 저장하기

Purang·2025년 2월 16일
data class FinancialEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0L,
    @ColumnInfo
    var categoryId: Long?,
    @ColumnInfo
    var title: String?, //적을 내용
    @ColumnInfo
    var content: String?, //적을 내용
    @ColumnInfo
    val createDate: String = LocalDateTime.now().toString(),
    @ColumnInfo
    var date: String?, //날짜
    @ColumnInfo
    var expenditure: Long?, //지출
    @ColumnInfo
    var income: Long?, //호득, 수입 등
    @ColumnInfo
    var selectColor: Color //not null 기본값 0
)

Entity에 Color를 저장할 변수를 추가하여 사용

하지만 RoomDB는 기본적으로 Color 타입을 저장할 수 없으므로 직렬화해서 저장하거나, 정수 값으로 변환해서 저장하는 방법을 사용해야 한다

class ColorConverter {
    @TypeConverter
    fun fromColor(color: Color?): Int? {
        return color?.toArgb() // Color를 Int로 변환 (ARGB)
    }

    @TypeConverter
    fun toColor(value: Int?): Color? {
        return value?.let { Color(it) } // Int를 Color로 변환
    }
}

해당 클래스를 선언하여

@TypeConverters(ColorConverter::class) // 추가
abstract class AppDatabase : RoomDatabase() {
	...
}

TypeConverters를 통해 자동 변환을 사용하려 시도하였다

하지만

java.lang.IllegalArgumentException: List has more than one element.
오류의 발생으로 빌드 에러가 발생했는데 https://github.com/google/ksp/issues/1700 마찬가지의 이슈 발생이 존재한다

위 이슈를 확인한 결과 거의 모두 Room에서 해당 오류가 발생한다는 것을 확인했고 당연하게도 저장하려한 Color 에서 문제가 발생했다고 생각하였다

다행히..

https://velog.io/@drskele/Error

해결법을 발견하여 적용하였다

data class FinancialEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0L,
    @ColumnInfo
    var categoryId: Long?,
    @ColumnInfo
    var title: String?, //적을 내용
    @ColumnInfo
    var content: String?, //적을 내용
    @ColumnInfo
    val createDate: String = LocalDateTime.now().toString(),
    @ColumnInfo
    var date: String?, //날짜
    @ColumnInfo
    var expenditure: Long?, //지출
    @ColumnInfo
    var income: Long?, //호득, 수입 등
    @ColumnInfo
    var selectColor: Int //not null 기본값 0
) {
    @Ignore
    val color = Color(selectColor)
}

이렇게 수정하여 Room에서 원하는 타입으로 저장이 가능하며 멤버 필드로 UI에서 사용할 때 selectColor 값을 Color 객체로 변환하는 역할을 하도록 설정이 가능하다는 것을 알았다

또한 이 방식을 사용할 경우 위에서 선언한
ColorConverter를 AppDatabase에 적용한 것을 지워야한다

현재 @TypeConverters(ColorConverter::class)로 등록되어 있지만, Room에서 FinancialEntity 내의 selectColor 컬럼이 이미 Int 타입이기 때문에 변환할 필요가 없기 때문이다

만약 지우지 않으면 Class is referenced as a converter but it does not have any converter methods. 오류가 발생한다

이제 Room에 selectColor를 저장할 때는 ColorConverter를 통해 Color를 Int로 변환하여 저장하고 UI에 반영할 때는 다시 Int를 Color로 변환하여 사용하면 된다

profile
몰입의 즐거움

0개의 댓글