Reputation: 76
I'm using Kotlin and retrofit+gson for network calls and i'm not able to deserializing responses for nested json
Here's My Network Module
class 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)
}
here's the models
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>()
}
and i'm getting Responses like this
HomeResponse(code=201, homeDataItem=m.a.b.b.a.b.b@ada2b35, message=All home locations and an advertisement, notifications=16)
What's wrong here ?
Upvotes: 0
Views: 1553
Reputation: 76
SOLVED Seems it's a problem between R8 and GSON and it can be solved by adding these lines to proguard rules
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep,allowobfuscation @interface com.google.gson.annotations.SerializedName
Upvotes: 0
Reputation: 8096
m.a.b.b.a.b.b@ada2b35
is actually a reference address, address at which it is stored.
NeitherHomeDataItem
implement toString()
nor it is a data class.
The data is correctly deserialized, you can also access it. But if you call println it will trigger its default toString
implementation which returns its reference address.
Workaround 1: Create your toString yourself:
fun toString() =
"HomeDataItem(specialEvent=$specialEvent, homeAdvertisment=$homeAdvertisment, locations=$locations)"
Workaround 2: Just make the HomeDataItem
a data class, it will generate toString
for you.
You have to put your variables inside constructor, you currently have make them instance variable and assigned null to them.
class HomeDataItem (
@SerializedName("specialEvent")
val specialEvent: SpecialEvent?=null
@SerializedName("homeAdvertisment")
val homeAdvertisment: HomeAdvertisment?=null
@SerializedName("locations")
val locations=ArrayList<LocationsItem>()
)
Upvotes: 0
Reputation: 167
Well you're using val for defining the elements and assigning a null value to them. Meaning that those elements won't be updated when response comes in.
val doesn't allow to change variable values, use var instead.
Upvotes: 2