Reputation: 505
I'm a beginner of kotlin Android developer. I come across this problem and I don't know how to resolve it.
I define a kotlin extension function Observable<T>.toTraditional()
in order to keep Rx flow call, but I met an exception.
Here is my code:
class Test {
@Test
fun test() {
val json = "{\"result\":{\"curPage\":1,\"data\":[{\"id\":1,\"name\":\"关雎\",\"dynasty\":\"先秦\",\"poet\":\"佚名\",\"content\":\"钟鼓乐之。\"},{\"id\":1213,\"name\":\"伐檀\",\"dynasty\":\"先秦\",\"poet\":\"佚名\",\"content\":\"钟鼓乐之。\"}],\"pageCount\":388,\"size\":20,\"total\":7756},\"status\":1,\"message\":\"成功\"}"
Observable.create<Response<RecommendListBean>> {
val response = getResponse<Response<RecommendListBean>>(json)
it.onNext(response)
}.toTraditional().subscribe({},{
println(it)
})
}
inline fun <reified T> getResponse(json: String): T {
return fromJson(json)
}
inline fun <reified T> Observable<T>.toTraditional(): Observable<T> {
return map {
val toJson = Gson().toJson(it)
// In fact, I convert simplified chinese in json to traditional chinese.
// Here, I intentionally omit that code to make my problem more clearly.
val result = fromJson<T>(toJson)
result
}
}
inline fun <reified T> fromJson(json: String?): T {
return Gson().fromJson<T>(json, object : TypeToken<T>() {}.type)
}
}
Also, I need to provide my three beans:
data class Response<T>(
val message: String,
@SerializedName(value = "result", alternate = ["data"])
val result: T,
val status: Int
)
data class RecommendListBean(
val curPage: Int,
val data: List<PoetryBean>,
val pageCount: Int,
val size: Int,
val total: Int
)
data class PoetryBean (
val content: String,
val dynasty: String,
val id: Int,
val name: String,
val poet: String
)
After runnint the above code, I get the error:
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.readbook.chinesepoetry.data.model.Response
I have look up this exception on the internet, many say that it's because kotlin generics erase. But, I exam my code, they really have reified
keyword.
Upvotes: 0
Views: 1748
Reputation: 51
fun <R :Any> Observable<R>.toTraditional(): Observable<R> {
return map {
val toJson = Gson().toJson(it)
// In fact, I convert simplified chinese in json to traditional chinese.
// Here, I intentionally omit that code to make my problem more clearly.
val result = Gson().fromJson<R>(toJson,it.javaClass)
result
}
}
just get the object's class
Upvotes: 1