无法为类、改造创建转换器

问题描述 投票:0回答:2

enter image description here 我使用图像是因为堆栈溢出中代码的格式给我带来了很多问题

这是我尝试调用以下接口的方法时遇到的错误:

interface TvShowService {

    @GET("tv/{tv_id}")
    suspend fun getDetails(
        @Path("tv_id") id: Int,
        @QueryMap queries: Map<String, String>
    ): TvShowDetailsDTO
}

在许多与我的问题相同的答案中,建议检查要映射的类中是否有相同的属性,但是,正如您所看到的,没有:

class TvShowDetailsDTO(
    backdropPath: String,
    @SerializedName("created_by")
    val createdBy: List<CreatedByDTO>,
    @SerializedName("episode_run_time")
    private val episodeRunTime: List<Int>,
    @SerializedName("first_air_date")
    val firstAirDate: String,
    genres: List<GenreDTO>,
    val homepage: String,
    id: Int,
    @SerializedName("in_production")
    val inProduction: Boolean,
    val languages: List<String>,
    @SerializedName("last_air_date")
    val lastAirDate: String,
    @SerializedName("last_episode_to_air")
    val lastEpisodeToAir: EpisodeDTO,
    name: String,
    val networks: List<NetworkDTO>,
    @SerializedName("next_episode_to_air")
    val nextEpisodeToAir: EpisodeDTO?,
    @SerializedName("number_of_episodes")
    val numberOfEpisodes: Int,
    @SerializedName("number_of_seasons")
    val numberOfSeasons: Int,
    originCountry: List<String>,
    originalLanguage: String,
    originalName: String,
    overview: String,
    popularity: Double,
    posterPath: String,
    @SerializedName("production_companies")
    val productionCompanies: List<ProductionCompanyDTO>,
    @SerializedName("production_countries")
    val productionCountries: List<ProductionCountryDTO>,
    val seasons: List<SeasonDTO>,
    @SerializedName("spoken_languages")
    val spokenLanguages: List<SpokenLanguageDTO>,
    val status: String,
    val tagline: String,
    val type: String,
    voteAverage: Double,
    voteCount: Int
) : TvShowDTO(
    backdropPath,
    firstAirDate,
    genres,
    id,
    name,
    originCountry,
    originalLanguage,
    originalName,
    overview,
    popularity,
    posterPath,
    voteAverage,
    voteCount
) {
    private fun formatTimeMeasurement(timeMeasurement: Int): String {
        val hours = timeMeasurement / 60
        val minutes = timeMeasurement % 60
        return String.format("%02d h %02d min", hours, minutes)
    }

    val formattedEpisodesRuntime: List<String>
        get() {
            return episodeRunTime.map { formatTimeMeasurement(it) }
        }


}

open class TvShowDTO(
    @SerializedName("backdrop_path")
    val backdropPath: String?,
    @SerializedName("first_air_date")
    private val firstAirDate: String,
    @SerialName("genre_ids")
    val genres: List<GenreDTO>,
    val id: Int,
    val name: String,
    @SerializedName("origin_country")
    val originCountry: List<String>,
    @SerializedName("original_language")
    val originalLanguage: String,
    @SerializedName("original_name")
    val originalName: String,
    val overview: String,
    val popularity: Double,
    @SerializedName("poster_path")
    val posterPath: String?,
    @SerializedName("vote_average")
    val voteAverage: Double,
    @SerializedName("vote_count")
    val voteCount: Int
) {
    private fun formatDate(date: String): String {
        val inputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        val outputFormat = SimpleDateFormat.getDateInstance()
        val formattedDate = inputFormat.parse(date)
        return outputFormat.format(formattedDate)
    }

    val formattedFirstAirDate: String
        get() {
            return if (firstAirDate.isNotEmpty()) {
                formatDate(firstAirDate)
            } else {
                ""
            }
        }
}

网络模块.kt

 @Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit =
    Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

我检查了依赖项,它们是最新的,我还有一个方法可以执行相同的操作,但对于电影来说并且它有效,因此它成功填充了

MovieDetailsDTO

可能存在的问题或至少可能的解决方案是什么。环顾四周,我发现的解决方案大多涉及重复属性之间的名称。

android kotlin gson retrofit2
2个回答
1
投票

解决方案

1°问题

有两个错误实际上涉及相同的父类和子类属性,但一开始我无法拦截它们。

让我们检查一下继承自

TvShowDetailsDTO
的两个类
TvShowDTO

    class TvShowDetailsDTO(
     backdropPath: String?,
     @SerializedName("created_by")
     val createdBy: List<CreatedByDTO>,
     @SerializedName("episode_run_time")
     private val episodeRunTime: List<Int>,
     @SerializedName("first_air_date")
     val firstAirDate: String, <-- ERROR
     genres: List<GenreDTO>,
   //...
   ):TvShowDTO(
     backdropPath,
     firstAirDate,
     / /...
   )

还有他的班父:

open class TvShowDTO(
    @SerializedName("backdrop_path")
    val backdropPath: String?,
    @SerializedName("first_air_date")
    private val firstAirDate: String,<-- THE REAL ONE
    //...
    )

通过将父类的此属性设置为私有,它在子类中不可见(TvShowDetailsDTO),因此定义了两次,显然无法映射,导致映射器中出现错误。

1°解决方案

解决方案是使父类属性仅在层次结构级别可见(protected),并在子类中删除重复属性前面的val关键字,如下所示:

open class TvShowDTO(
@SerializedName("backdrop_path")
val backdropPath: String?,
@SerializedName("first_air_date")
protected val firstAirDate: String,

class TvShowDetailsDTO(
backdropPath: String?,
@SerializedName("created_by")
val createdBy: List<CreatedByDTO>,
@SerializedName("episode_run_time")
private val episodeRunTime: List<Int>,
firstAirDate: String,

2°问题

另一个非常相似的问题存在于

List<CreatedByDTO>
TvShowDetailsDTO
属性中,这里是类:

    class CreatedByDTO(
    @SerializedName("credit_id")
    val creditId: String,
    val gender: Int?,
    id: Int,
    name: String,
    profilePath: String?
) : PersonDTO(
    id, name, profilePath, gender
)


open class PersonDTO(
val adult: Boolean,
@SerializedName("also_known_as")
val alsoKnownAs: List<String>,
val biography: String,
private val birthday: String?,
@SerializedName("deathday")
private val deathDay: String?,
private val gender: Int?,

始终是在父类中创建私有属性的类层次结构会导致相同的错误,在这种情况下,该属性被定义两次gender,解决方案始终相同,在父类中将其设为protected,这样从子类中删除关键字和 @SerializedName


0
投票

当我尝试添加第二组触及我的

provideRetrofit()
版本的调用时,我在 Android 应用程序中遇到了同样的错误。原始呼叫者需要
ScalarsConverterFactory
,新呼叫者需要
GsonConverterFactory
。我通过检查请求 URL 中是否存在仅出现在标量请求中的特定关键字来解决此问题,以相应地翻转转换器工厂。这不是一个出色的解决方案,但希望这可以帮助其他人,如果他们对转换器工厂有同样的问题。

© www.soinside.com 2019 - 2024. All rights reserved.