Android Room2.0之@TypeConverters使用

Jack愛學習發表於2018-11-13

前言

Room是Google 新推出的Jetpack元件庫中一款運算元據庫的SQLITE ORM庫。其風格類似Retrofit,使用註解+介面宣告形式,簡化了資料庫的操作。

隨著時間的推遲,Room迭代更新的版本也越來越快,到目前(本文所寫時間為止)最新的版本是2.1.0-alpha02,它的一些API也做了調整,本文是記錄一次@TypeConverters(ThumbConverter::class)的使用

本文是以Kotlin語言例項,Java語法類似

定義實體類 News.kt
@Entity
data class News(
        @PrimaryKey
        var row: String,
        var title: String = "",
        var type: Int = 2,
        val thumb: List<String>?,
        var content_time: String? = "",
        var source: String? = "",
        var hot: Int = 0
)

複製程式碼

發現Android Studio會報如下錯誤,編譯不通過,原因是@Entity定義的thumb欄位無法識別List?型別(非基礎型別),最終對映成資料庫欄位,所以Room提供一個解決方案:手動做型別轉換,用轉換類告訴Room該如何轉換成資料庫支援的型別。

/Users/Documents/code/news_android2.0/module_news/build/tmp/kapt3/stubs/debug/com/zm/module/news/repository/entity/News.java:15: 錯誤: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
    private final java.util.List<java.lang.String> thumb = null;
                                                   ^

複製程式碼
定義TypeConverter類
class ThumbConverter {
    @TypeConverter
    fun getThumbFromString(value: String):List<String>? {
        return value.split(",")
    }

    @TypeConverter
    fun storeThumbToString(list: List<String>): String {
        val str = StringBuilder(list[0])
        list.forEach {
            str.append(",").append(it)
        }
        return str.toString()
    }
}

複製程式碼

@TypeConverter的兩個方法是成對出現的,方法名稱可以任意命名,重點在入參和出參型別,必須是需要轉換的型別和最終轉換後的型別,這點想一下原理能明白了。上面示例寫入時將List型別轉換成以“,”逗號拼接的String型別,讀取時再將逗號分割的字串轉換成List型別。

Room 2.0@TypeConverters調整

經過上面的定義依然是無法編譯通過的,原因是Entity類還需要新增這裡@TypeConverters,強調一下**@TypeConverters 是有s的,要與轉換類方法上的@TypeConverter做區別。在現有的很多文章裡提到@TypeConverters都是加到屬性上的,如:stackoverflow上的問答,在Room 2.0**是會報錯的,因為現在已經改為加到Entity類上面了。

錯誤的

@TypeConverters(ThumbConverter::class)
        val thumb: List<String>?,

複製程式碼

正確的

@Entity
@TypeConverters(ThumbConverter::class)
data class News(
        @PrimaryKey
        var row: String,
        var title: String = "",
        var type: Int = 2,
        val thumb: List<String>?,
        var content_time: String? = "",
        var source: String? = "",
        var hot: Int = 0
)
複製程式碼

後記

多個轉換類可以@TypeConverters(ThumbConverter::class,XXXX::Converter::class)定義。

相關文章