第一种封装类型
子 <HttpModel<JavaBean>>
父 <T:HttpModel<*>>
祖 <T>
代码比较严谨,但是子类中使用(一般以匿名内部类回调的形式存在)时比较繁琐,每次都需要重复的传入共有泛型 HttpModel
。
封装代码:
internal abstract class CollCallback<T : HttpModel<*>> : Callback<T>() {
companion object {
@Suppress("SpellCheckingInspection")
val mGson = Gson()
}
override fun parseNetworkResponse(response: Response?, id: Int): T? {
response ?: return null
val json = response.body()?.string()
Logs.json(json)
return mGson.fromJson(json, getSuperModelClass(this.javaClass))
}
private fun getSuperModelClass(clazz: Class<*>): Type? {
println("$clazz")
val superType = clazz.genericSuperclass
println("superType = ${superType}")
if (superType is ParameterizedType) {
val types = superType.actualTypeArguments
types.forEach { println("getSuperModelClass: $it") }
return types[0]
} else {
// throw RuntimeException("Missing type param")
println("Missing type param")
return null
}
}
override fun onError(call: Call?, e: Exception?, id: Int) {
}
}
Junit测试代码:
@Test
fun getSuperModelClassTest() {
val callback = object : CollCallback<HttpModel<Exif>>() {
override fun onResponse(response: HttpModel<Exif>?, id: Int) {
println("ExampleTest.onResponse() called with: response = [$response], id = [$id]")
}
}
val response = Response.Builder().body(
ResponseBody.create(
MediaType.parse("application/json;charset=utf-8"),
"{\"code\":200,\"message\":\"ok\",\"data\":{\"album\":\"Camera\"}}"
)
).request(Request.Builder().url("http://www.baidu.com").build())
.message("msg")
.protocol(Protocol.HTTP_2)
.code(201)
.build()
println("开始解析")
val model = callback.parseNetworkResponse(response, 101)
callback.onResponse(model, 101)
assertEquals("Camera", model!!.data!!.album)
}
第二种封装方式
子 <JavaBean>
父 <T>
祖 <HttpModel<T>>
子类中使用(一般以匿名内部类回调的形式存在)时比较便捷,每次只需要传入Bean的类型即可。但是在封装的代码中会对业务层共有层耦合紧密一些,比如;修改了字段data的名字,需要修改此封装代码。但是第一种封装方式中只需要修改HttpModel即可。而且此处用到了强制类型转换,并做了两次json解析。
internal abstract class CollCallback1<T> : Callback<HttpModel<T>>() {
companion object {
@Suppress("SpellCheckingInspection")
val mGson = Gson()
}
override fun parseNetworkResponse(response: Response?, id: Int): HttpModel<T>? {
response ?: return null
val json = response.body()?.string()
Logs.json(json)
val httpModel = mGson.fromJson<HttpModel<T>>(json, HttpModel::class.java)
val dataJson = mGson.toJson(httpModel.data)
println("dataJson = $dataJson")
val data = mGson.fromJson<Any>(dataJson, getSuperModelClass(this.javaClass))
@Suppress("UNCHECKED_CAST")
httpModel.data = data as T
return httpModel
}
private fun getSuperModelClass(clazz: Class<*>): Type? {
val superType = clazz.genericSuperclass
if (superType is ParameterizedType) {
val types = superType.actualTypeArguments
types.forEach { println("getSuperModelClass: $it") }
return types[0]
} else {
throw RuntimeException("Missing type param")
}
}
override fun onError(call: Call?, e: Exception?, id: Int) {
}
}
Junit测试代码:
@Test
fun getSuperModelClassTest2() {
val callback = object : CollCallback1<Exif>() {
override fun onResponse(response: HttpModel<Exif>?, id: Int) {
println("ExampleTest.onResponse() called with: response = [$response], id = [$id]")
}
}
val response = Response.Builder().body(
ResponseBody.create(
MediaType.parse("application/json;charset=utf-8"),
"{\"code\":200,\"message\":\"ok\",\"data\":{\"album\":\"Camera\"}}"
)
).request(Request.Builder().url("http://www.baidu.com").build())
.message("msg")
.protocol(Protocol.HTTP_2)
.code(201)
.build()
println("开始解析")
val model = callback.parseNetworkResponse(response, 101)
callback.onResponse(model, 101)
assertEquals("Camera", model!!.data!!.album)
}
网友评论