【问题标题】:Android Kotlin - Storing of Gson casted API data into a Room DatabaseAndroid Kotlin - 将 Gson 转换的 API 数据存储到房间数据库中
【发布时间】:2020-03-31 15:46:02
【问题描述】:

我正在使用okhttp 从 API 中获取 Json 数据,将其转换为 Gson 以用于其他目的,同时将 API 数据存储到 Room Database 中。 (可以是API json数据本身的存储,也可以是转换后的Gson版本)但是,我在这方面没有成功,希望你能指出我出错的方向。

我想我缺少一个 typeConverter 来转换从 API 检索并转换为 GSON 的数据,以存储在 Room database 中。但是我不确定我在这方面是否正确,或者我的方法首先是否正确。

或者我有一个Entities data class,但gsonData 被转换为SampleData data class,这可能是一个问题吗?

DataGetter

...
...
...
// this suspend function is run within a coroutine.
private suspend fun APICall(url: String, pageNumber: Int, context: Context){
    val urlRequest = Request.Builder().url(url).build()  // Building of the URL to fetch data
    httpClient.newCall(urlRequest).enqueue(object : Callback {
        // onFailure -> cutting this out to shorten code
        // onResponse is where I am fetching the data and calling put to DB
        override fun onResponse(call: Call, response: Response) {
            val dataString = response.body!!.string()
            val gsonData = gsonResult.fromJson(dataString, SampleData::class.java)
            // Do some other stuffs with gsonData separately. This doesn't return anything to gsonData. 
            putToRoomDb(gsonData, context)  // This will eventually be done via another coroutine.
        }
    }
}

private suspend fun putToRoomDb(sampleData: SampleData, context: Context) {        
    val db = MyOnlyDatabase.getInstance(context)
    db.MyOnlyDao().updateOrInsert(sampleData)
}

实体

@Entity(tableName = "sample_data_code_names")
data class SampleDataEntities(
    @PrimaryKey
    var Code: Int,
    val Name: String,
    val Description: String,
    val Item1: String,
    val Item2: String
) 

@Dao
interface SampleDataDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun updateOrInsert(sampleDataEntities: SampleDataEntities)
}

数据库

@Database(entities = [SampleDataEntities::class], version = 1, exportSchema = false)
abstract class MyOnlyDatabase: RoomDatabase() {
    abstract fun sampleDataDao(): SampleDataDao 

    companion object {  
        @Volatile
        private var instance: MyOnlyDatabase? = null    
        fun getInstance(context: Context): MyOnlyDatabase{
            return instance ?: synchronized(this) {                   
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): MyOnlyDatabase{
            return Room.databaseBuilder(context, MyOnlyDatabase::class.java, "MyOnlyDatabase.db")
                .fallbackToDestructiveMigration()                   
                .build()                                                     
        }
    }
}

注意:下面是data classgsonData 被转换成。

data class SampleData(val value: List<SampleDataInfoItems>)
data class SampleDataInfoItems(
    val Code: String,
    val Name: String,
    val Description: String,
    val Item1: BigDecimal,
    val Item2: BigDecimal
)

【问题讨论】:

    标签: android kotlin gson android-room


    【解决方案1】:

    您没有根据来自服务器的 JSON 响应来注释您的字段。

    data class SampleDataInfoItems(
        @SerializedName("name_this_field_on_json")
        val Code: String,
        @SerializedName("and_so_on_for_all_fields")
        val Name: String,
        val Description: String,
        val Item1: BigDecimal,
        val Item2: BigDecimal
    )
    

    另外,我认为您需要 GsonConververFactory 进行改造。

    【讨论】:

    • 你是想说@Entity(tableName = "sample_data_code_names") 应该在我的SampleDataInfoItems 数据类上吗?但是传递的gsonData 来自data class SampleData 而不是data class SampleDataInfoItems
    • 您可以使用不同的模型并提取它们,也可以对 db 和 gson 使用相同的模型
    • 嗯,我想对 db 和 gson 使用相同的模型是有意义的。但是,我不明白的是,gsonData 的类型为SampleData。其中包含SampleDataInfoItems。不会是类型不匹配吧?
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多