您可以使用继承自 WebView 的自定义类,或者如果您愿意,可以添加扩展功能。逻辑基本相同:
private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {
val savedWebViewClient = getWebViewClient()
webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
if (url != postUrl) {
view.post {
webViewClient = savedWebViewClient
}
return savedWebViewClient?.shouldInterceptRequest(view, url)
}
Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
val httpsUrl = URL(url)
val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
conn.requestMethod = "POST"
additionalHttpHeaders.forEach { header ->
conn.addRequestProperty(header.key, header.value)
}
conn.outputStream.write(postData)
conn.outputStream.close()
val responseCode = conn.responseCode
Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
view.post {
webViewClient = savedWebViewClient
}
// typical conn.contentType is "text/html; charset=UTF-8"
return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
}
}
loadUrl(postUrl, additionalHttpHeaders)
}
为简洁起见,对上面的代码进行了编辑,隐藏了大多数错误检查。要为 26 级以下的 API 工作,我使用反射来提取savedWebViewClient
.
在现实生活中,您还希望覆盖新方法,并将WebViewClientshouldInterceptRequest(view: WebView, request: WebResourceRequest)
的所有其他方法委托给. 可能PostWithHeadersWebView类(也覆盖)可以让您的生活更轻松。savedWebViewClient
setWibViewClient()