抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

关于 Android okHttp Gzip 的简单处理

雨若下得及时,可解干旱,

但雨若下得任性,可致洪涝。

服务端并不是默认都发送gzip的数据包,大家都知道okHttp有机制去自动解析gzip数据,但是如果是我们自己添加header去请求的gzip包,则需要手动处理了。

在网上找了一个解包方案,用了一段时间,感觉还行。直接用在okHttp上作为一个拦截器即可。

class GzipNetworkInterceptor(val context: Context) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request: Request = chain.request()
        val response = chain.proceed(request)
        val body = response.body
        val result = if (body != null && response.header("Content-Encoding") == "gzip") {
            val mediaType: MediaType? = body.contentType()
            var data = body.bytes()
            data = uncompress(data)
            //創建一個新的responseBody,返回進行處理
            response.newBuilder()
                    .body(data.toResponseBody(mediaType))
                    .build()
        } else {
            response
        }
        return result
    }

    /**
     * 字節數組解壓
     */    private fun uncompress(bytes: ByteArray): ByteArray {
        val out = ByteArrayOutputStream()
        val `in` = ByteArrayInputStream(bytes)
        var gzipInputStream: GZIPInputStream? = null
        try {
            gzipInputStream = GZIPInputStream(`in`)
            val buffer = ByteArray(4096)
            var n: Int
            while (gzipInputStream.read(buffer).also { n = it } >= 0) {
                out.write(buffer, 0, n)
            }
        } catch (e: IOException) {
            println("gzip uncompress error.")
        } finally {
            gzipInputStream?.close()
        }
        return out.toByteArray()
    }
}

用的时候:

addNetworkInterceptor(GzipNetworkInterceptor(context))

其实也可以使用okHttp提供的解包方法:

在ohHttp的BridgeInterceptor中(全局搜Scope会找到)

框出的就是关键代码,拿来用即可,不过没验证。但是看代码会发现,一个是使用的Java的GZIPInputStream,一个是Square的GzipSource,稍微看了下,没问题就没折腾了。

以上。


0条评论

发表评论