【问题标题】:Make Kotlin Serializer work with Retrofit让 Kotlin Serializer 与 Retrofit 一起工作
【发布时间】:2020-06-30 09:52:06
【问题描述】:

我不能让 Kotlin Serializer 与 Retrofit 一起工作。我正在使用 com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.5.0 包和 Retrofit。

数据类

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable


@Serializable
data class YelpSearchResult(
    @SerialName("total") val total: Int,
    @SerialName("businesses") val restaurants: List<YelpRestaurant>
)

data class YelpRestaurant(
    val name: String,
    val rating: Double,
    val price: String,
    @SerialName("review_count") val numReviews: Int,
    @SerialName("distance") val distanceInMeters: Double,
    @SerialName("image_url") val imageUrl: String,
    val categories: List<YelpCategory>,
    val location: YelpLocation
) {

    fun displayDistance(): String {
        val milesPerMeter = 0.000621371
        val distanceInMiles = "%.2f".format(distanceInMeters * milesPerMeter)
        return "$distanceInMiles mi"
    }
}

data class YelpCategory(
    val title: String
)

data class YelpLocation(
    @SerialName("address1") val address: String
)

服务接口

public interface YelpService {
    @GET("businesses/search")
    fun searchRestaurants(
        @Header("Authorization") authHeader: String,
        @Query("term") searchTerm: String,
        @Query("location") location: String): Call<YelpSearchResult>
}

活动

    val contentType = MediaType.get("application/json")
    val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(Json.asConverterFactory(contentType))
            .build()

    val yelpService = retrofit.create(YelpService::class.java)


    yelpService.searchRestaurants("Bearer ${api_key}",
        "Something", "Some Location").enqueue(
            object: Callback<YelpSearchResult> {
                override fun onFailure(call: Call<YelpSearchResult>, t: Throwable) {
                    Log.d("MainActivity", "err ${t}")

                }
                override fun onResponse(call: Call<YelpSearchResult>, response: Response<YelpSearchResult>) {
                    Log.d("MainActivity", "succ ${response}")
                }
            }
    )

运行时,抛出的异常是,

java.lang.RuntimeException:无法启动活动 组件信息{com.xx.xx/com.xx.xx.MainActivity}: java.lang.IllegalArgumentException:无法创建转换器 class com.xx.xx.YelpSearchResult

无法为类 com.xx.xx.YelpSearchResult 创建转换器 对于方法 YelpService.searchRestaurants

原因:kotlinx.serialization.SerializationException: 无法定位 YelpSearchResult 类的无参数序列化程序。对于通用 类,如列表,请明确提供序列化器。

我做错了什么?感谢您的任何指示。

【问题讨论】:

标签: android kotlin serialization retrofit kotlin-android-extensions


【解决方案1】:

你忘了把@Serializable注解放在YelpRestaurant上面

@Serializable
data class YelpRestaurant {
...
}

YellCategoryYelpLocation 也应该有注释。

【讨论】:

    【解决方案2】:

    在您的数据类中添加 Serializable

    import kotlinx.serialization.SerialName
    import kotlinx.serialization.Serializable
    
    
    @Serializable
    data class YelpSearchResult(
        @SerialName("total") val total: Int,
        @SerialName("businesses") val restaurants: List<YelpRestaurant>
    )
    
    @Serializable
    data class YelpRestaurant(
        val name: String,
        val rating: Double,
        val price: String,
        @SerialName("review_count") val numReviews: Int,
        @SerialName("distance") val distanceInMeters: Double,
        @SerialName("image_url") val imageUrl: String,
        val categories: List<YelpCategory>,
        val location: YelpLocation
    ) {
    
        fun displayDistance(): String {
            val milesPerMeter = 0.000621371
            val distanceInMiles = "%.2f".format(distanceInMeters * milesPerMeter)
            return "$distanceInMiles mi"
        }
    }
    
    @Serializable
    data class YelpCategory(
        val title: String
    )
    
    @Serializable
    data class YelpLocation(
        @SerialName("address1") val address: String
    )
    

    【讨论】:

      【解决方案3】:

      将此依赖项添加到您的 gradle:

      implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
      

      更新您的改造构建器以使用 GsonConverterFactory,如下所示:

       val retrofit = Retrofit.Builder()
                  .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(Gson()))
                  .build()
      

      并删除 @Serializable 注释,因为不需要

      【讨论】:

      • 他没有使用 Gson 进行序列化,他使用的是 kotlin 序列化程序..您将使用 Gson..
      猜你喜欢
      • 1970-01-01
      • 2016-12-13
      • 2016-10-06
      • 2011-11-30
      • 2014-02-19
      • 2011-09-03
      • 2013-05-01
      • 2018-05-30
      • 2014-03-17
      相关资源
      最近更新 更多