美文网首页
网络封装之关于泛型解析

网络封装之关于泛型解析

作者: 钦_79f7 | 来源:发表于2019-12-18 11:21 被阅读0次

第一种封装类型

子 <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)
    }

相关文章

网友评论

      本文标题:网络封装之关于泛型解析

      本文链接:https://www.haomeiwen.com/subject/bcnynctx.html