【问题标题】:Insert retrofit response in Room Kotlin在 Room Kotlin 中插入改造响应
【发布时间】:2023-03-27 10:59:01
【问题描述】:

我正在尝试将 response.body() 插入到数组列表中,但它正在为空。这个想法是将数据从服务器发送到数据库。我可以毫无问题地在recyclerview中显示它,但不知道如何在本地存储所有数据。

代码如下:

    val service = client!!.create(ApiInterface::class.java)
    val call = service.pOIs
    call!!.enqueue(object : Callback<PoiResponse?> {
        override fun onResponse(call: Call<PoiResponse?>, response: Response<PoiResponse?>) {
            if (response.isSuccessful) {
                
                val result = response.body()
                //here i send the response to a poi model to show it in a recyclerview, works fine
                val poiList: ArrayList<Poi>? = result?.list
                
                //same data, but for persistence
                val poiRoomList: ArrayList<PoiRoom>? = result?.roomList //here is getting null

                onFinishedListener!!.onFinished(poiList, poiRoomList)

回复:

class PoiResponse {
    var list: ArrayList<Poi>? = null
    var roomList: ArrayList<PoiRoom>? = null
}

道:

@Dao
interface PoiDao {

   @Insert(onConflict = OnConflictStrategy.IGNORE)
   fun insert(poiRoom: PoiRoom)

   @Insert(onConflict = REPLACE)
   fun insertAllPois(poisRoomList: List<PoiRoom>?);


   @Query("SELECT * FROM poi_table")
   fun getAllPois(): LiveData<List<PoiRoom>>
   
}

实体:

@Entity(tableName = "poi_table")
class PoiRoom(
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0,
        @ColumnInfo(name = "title")
        val title: String,
        @ColumnInfo(name = "address")
        val address: String,
        @ColumnInfo(name = "transport")
        val transport: String,
        @ColumnInfo(name = "email")
        val email: String,
        @ColumnInfo(name = "geocoordinates")
        val geocoordinates: String,
        @ColumnInfo(name = "description")
        val description: String)
       

Json 响应,兴趣点列表:

{
  "list": [
    {
      "id": "1",
      "title": "Casa Batlló",
      "geocoordinates": "41.391926,2.165208"
    },
    {
      "id": "2",
      "title": "Fundació Antoni Tàpies",
      "geocoordinates": "41.39154,2.163835"
    },

数据库类:

@Database(entities = [PoiRoom::class], version = 1)
abstract class PoiRoomDatabase : RoomDatabase() {

    abstract fun poiDao(): PoiDao

    companion object {
        @Volatile
        private var INSTANCE: PoiRoomDatabase? = null

        fun getDatabase(
                context: Context,
                scope: CoroutineScope
        ): PoiRoomDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        PoiRoomDatabase::class.java,
                        "poi_database"
                )
                        .fallbackToDestructiveMigration()
                        .build()
                INSTANCE = instance
                instance
            }
        }

    }
}

解决方案:

1º) 从响应中删除数组列表

2º) 使用 poilist 映射的 Roomlist,如下所示:

  val mappedRoomList =   poiList?.map { PoiRoom(it.id, it.title, it.address, it.transport, it.email, it.geocoordinates, it.description) }

3º) 创建了将映射列表添加到房间数据库的方法:

override fun sendDataToRoomDataBase(poiOfflineList: List<PoiRoom?>?) {

     poiDao?.insertAllPois(poiOfflineList)

    }

4º)创建的转换器:

class PoiConverters {
  
        private val gson = Gson()

        @TypeConverter
        fun stringToListPoi(data: String?): List<Poi?>? {
            if (data == null) {
                return Collections.emptyList()
            }
            val listType: Type = object :
                    TypeToken<List<Poi?>?>() {}.type

            return gson.fromJson<List<Poi?>>(data, listType)
        }

        @TypeConverter
        fun listPoiToString(list: List<Poi?>?): String? {
            return gson.toJson(list)
        }
}

仅此而已:)

【问题讨论】:

  • 您能否将您的 PoiResponse 发布为 json 格式以及您的数据库类?
  • 两者都添加了。顺便说一句,数据库的创建和手动插入是可行的,只是不知道为什么当我向数组发送响应时会变为空。

标签: android kotlin retrofit


【解决方案1】:

好吧,据我所知,请检查您的 Json 响应:您只有“list”键,而不是“roomList”键。这意味着,当您解析响应 Json 并插入 ArrayList 时,您只会“填充”列表类型的对象,而不是 roomList,因为它不存在! 我要做的是映射您的响应列表并使用 map 函数将其映射到您的 RoomList 对象。 试试这样的:

override suspend fun insertAllPoiIntoDb(poiList: List<Poi>) {
   yourDatabase.yourDao().insertAllObjectsFunction(
     poiList.map {
       it.toRoomObject()
     }
  )
}

toRoomObject() 函数代表你的 Poi 对象中的一些函数逻辑,它将 Poi 转换为 RoomPoi(即对象的构造)。

【讨论】:

  • 哦,是的!那是真的,没有检查。然后我必须迭代列表并将值发送到第二个(roomList)对吗?。
  • @Insert(onConflict = REPLACE) 有趣的 insertAllPois(poisRoomList: List?);调用此函数并将您的列表插入其中
  • 处理它,用这个方法调用它: override fun sendDataToRoomDataBase(poiList: List?) { poiDao?.insertAllPois(poiList) } 只是类型不匹配
  • 你必须将你的 poi 映射到 PoiRoom 对象(即 List)
  • 用解决方案更新了问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 2020-02-22
  • 2023-03-30
  • 2021-06-26
  • 2019-03-17
  • 2021-05-25
相关资源
最近更新 更多