如何在会议室数据库中正确存储和检索对象的哈希图?

时间:2020-07-28 11:27:55

标签: android hashmap android-sqlite android-room android-livedata

我试图在房间数据库中存储一个api响应,然后将本地数据作为实时数据获取。response(DistrictName)看起来像这样:

const val PRIMARY_KEY_DISTRICTS = 0
@Entity(tableName = "all_districts_table")
data class DistrictName (
    @TypeConverters(DistrictsMapTypeConverter::class)
    var districtValue: Map<String, DistrictValue>){

    init {
        districtValue = HashMap()
    }

    @PrimaryKey
    var primaryKey:Int = PRIMARY_KEY_DISTRICTS
    var networkFetchTime:Long = 0
}

“ DistrictValue”类如下所示:

data class DistrictValue(
    @TypeConverters(DistrictsTypeConverter::class)
    @SerializedName("districtData")
    var districts: Map<String, Districts>
) {
    init {
        districts = HashMap()
    }
}

“区”类如下:

data class Districts(
    @SerializedName("active")
    val activeCase: String?,

    @SerializedName("confirmed")
    val totalCase: String?,

    @SerializedName("recovered")
    val recovered: String?,

    @SerializedName("deceased")
    val deaths: String?
)

我添加了一个类型转换器,用于将那些map 转换为string和vise-varsa。我的类型转换器如下:

object DistrictsMapTypeConverter {

    @TypeConverter
    @JvmStatic
    fun fromAllDistrictMap(allDistrict: Map<String,DistrictValue?>?): String? {
        if (allDistrict == null) {
            return null
        }
        val gson = Gson()
        val type: Type = object : TypeToken<Map<String,DistrictValue?>?>() {}.type
        return gson.toJson(allDistrict, type)
    }

    @TypeConverter
    @JvmStatic
    fun toAllDistrictMap(allDistrictString: String?): Map<String,DistrictValue?>? {
        if (allDistrictString == null) {
            return null
        }
        val gson = Gson()
        val type: Type = object : TypeToken<Map<String,DistrictValue?>?>() {}.type
        return gson.fromJson<Map<String,DistrictValue?>?>(allDistrictString, type)
    }
}

这是我的教学班:

@Dao
interface AllDistrictsDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAllDistricts(allDistricts:DistrictName)

    @Query("select * from all_districts_table")
    fun getLocalAllDistricts():LiveData<DistrictName>

    @Query("select * from all_districts_table")
    fun getLocalAllDistrictsNonLive():DistrictName

}

我正在进行api调用,并将响应保存在存储库中的房间内。这是我的存储库类:

class Repository(private val allDistrictsDao: AllDistrictsDao,
                 private val indiaDataApiService: IndiaDetailApiService
) {

    suspend fun getAllDistrictsData():LiveData<DistrictName>{

        return withContext(Dispatchers.IO){

            updateAllDistricts()
            return@withContext allDistrictsDao.getLocalAllDistricts()
        }
    }

    private suspend fun updateAllDistricts() {

        if (allDistrictsDao.getLocalAllDistrictsNonLive()==null){
            fetchAllDistricts()
            return
        }

        val lastFetchTime = allDistrictsDao.getLocalAllDistrictsNonLive().networkFetchTime
        if (isNetworkFetchNeeded(lastFetchTime)){
            fetchAllDistricts()
        }
    }

    private suspend fun fetchAllDistricts() {

        try {
            val request = indiaDataApiService.getAllDistricts()

            if (request.isSuccessful){

                val allDistricts = request.body()
                allDistricts?.networkFetchTime = EpochTimeProvider.getCurrentEpoch()
                allDistrictsDao.insertAllDistricts(allDistricts!!)

            }
            else
                Log.e("NetworkError", request.errorBody().toString())

        }catch (e:NoInternetException){
            Log.e("Network",e.message.toString())
        }
    }

    private fun isNetworkFetchNeeded(lastFetchTime:Long): Boolean {

        val time = EpochTimeProvider.getTimeMinus(EpochTimeProvider.getCurrentEpoch(),2)

        return time >= lastFetchTime
    }

}

但是当我尝试从数据库访问该数据时,它返回我LiveData但正文为空。我打印了输出:

2020-07-28 16:51:46.616 30862-30862/com.example.covid19trackerkotlin E/Output: DistrictName(districtValue={})

我认为我做错了什么。我不确定将哈希表存储在房间内的正确方法。请帮我解决这个问题。

0 个答案:

没有答案