Kotlin + дооснащение + десериализация Gson не работает для вложенных json - PullRequest
0 голосов
/ 27 апреля 2020

Я использую Kotlin и retrofit + gson для сетевых вызовов, и я не могу десериализовать ответы для вложенных json

Вот мой сетевой модуль

класса NetworkModule ( ) {

@Provides
internal fun provideGson(): Gson {
    return GsonBuilder()
            .setLenient()
            .disableHtmlEscaping()
            .create()
}


@Provides
internal fun provideOkHttpClient(): OkHttpClient {
    val builder = OkHttpClient.Builder()
    builder.readTimeout(60, TimeUnit.SECONDS)
    builder.connectTimeout(60, TimeUnit.SECONDS)
    val logging = HttpLoggingInterceptor()
    logging.level = HttpLoggingInterceptor.Level.BODY
    val client = OkHttpClient.Builder()
            .addInterceptor(logging)
            .build()

    return client
}

@Provides
internal fun provideLuqyaApi(gson: Gson, okHttpClient: OkHttpClient): LuqyaApi {
    return Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL_PLUS)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpClient)
            .build().create(LuqyaApi::class.java)
}

вот модели

data class HomeResponse(

    @field:SerializedName("code")
    @Expose
val code: String? = null,

    @field:SerializedName("data")
    @Expose
val homeDataItem: HomeDataItem,

    @field:SerializedName("message")
    @Expose
val message: String? = null,

    @field:SerializedName("notifications")
    @Expose
val notifications: Int? = null

)

class HomeDataItem {
@SerializedName("specialEvent")
val specialEvent: SpecialEvent?=null

@SerializedName("homeAdvertisment")
val homeAdvertisment: HomeAdvertisment?=null

@SerializedName("locations")
val locations=ArrayList<LocationsItem>()
}

, и я получаю ответы, подобные этому

HomeResponse (код = 201, homeDataItem = mabbab b@ada2b35, message = Все домашние местоположения и реклама, уведомления = 16)

Что здесь не так?

Ответы [ 3 ]

1 голос
/ 27 апреля 2020

Ну, вы используете val для определения элементов и присвоения им нулевого значения. Это означает, что эти элементы не будут обновляться при поступлении ответа.

val не позволяет изменять значения переменных, вместо этого используйте var .

0 голосов
/ 29 апреля 2020

решено Кажется, что это проблема между R8 и GSON, и ее можно решить, добавив эти строки в правила proguard

-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep,allowobfuscation @interface com.google.gson.annotations.SerializedName
0 голосов
/ 27 апреля 2020

m.a.b.b.a.b.b@ada2b35 на самом деле является ссылочным адресом, адресом, по которому он хранится.

Ни HomeDataItem не реализует toString(), ни класс данных.

Данные верны десериализованный, вы также можете получить к нему доступ. Но если вы вызовите println, он запустит реализацию по умолчанию toString, которая вернет свой ссылочный адрес.

Обходной путь 1: Создайте свою строку toString самостоятельно:

fun toString() =
    "HomeDataItem(specialEvent=$specialEvent, homeAdvertisment=$homeAdvertisment, locations=$locations)"

Обходной путь 2: Просто сделайте HomeDataItem классом данных, он сгенерирует для вас toString.


ПРИМЕЧАНИЕ:

Вы должны поместить свои переменные внутри конструктора у вас есть переменная экземпляра и им присвоено значение null.

class HomeDataItem (
@SerializedName("specialEvent")
val specialEvent: SpecialEvent?=null

@SerializedName("homeAdvertisment")
val homeAdvertisment: HomeAdvertisment?=null

@SerializedName("locations")
val locations=ArrayList<LocationsItem>()
)
...