在现在的客户端开发过程中,越来越多的需要和前端H5页面进行交互。
首先先配置WebView
1.开启Kotlin与H5通信的开关
mWebView.settings.javaScriptEnabled = true
2.设置两个WebViewClient
mWebView.webViewClient = MyViewClient()
mWebView.webChromeClient = MyWebChormeClient()
private class MyViewClient : WebViewClient() {
//页面加载完调用
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
}
private class MyWebChormeClient : WebChromeClient() {
//加载进度条
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
}
}
3.加载网页
mWebView.loadUrl("https://www.google.com/")
这样基本的WebView就配置好了
接下来看H5如何调用Kotlin代码
// mWebView.addJavascriptInterface(对象,字符串) 对象:方法名 字符串:就是参数对象的别名
mWebView.addJavascriptInterface(JavaScriptMethods(this, mWebView), "jsInterface")
这里的jsInterface是为了js调用kotlin,因为两个语言不认识,需要起一个名字。然后以起好的名字为类名创建一个Kotlin类封装给H5调用的方法。
看一个小例子
kotlin方法
@JavascriptInterface //android4.2以后 必须加上此注解
fun showToast(json: String) {
Toast.makeText(mContext, json, Toast.LENGTH_SHORT).show()
}
js调用
var json = {"name":"html5"}
window.jsInterface.showToast(JSON.stringify(json))
接下来看Kotlin如何调用H5代码
一般可以在网页加载完成,也就是WebViewClient的onPageFinished回调方法里
同样还是一个小例子
js代码
var showMessage = function(json) {
alert(JSON.stringify(json))
};
Kotlin代码
//mWebView.loadUrl("javascript:方法名(参数)")
var json = JSONObject()
json.put("name", "Kotlin")
mWebView.loadUrl("javascript:showMessage(" + json.toString() + ")")
这样就完成了Kotlin和H5的互相调用,不过这样会有一个问题,方法名已经写死了,Kotlin和H5的耦合会很深,万一不小心改了方法名,那么便会造成错误。
所以便有了CallBack机制,这也是支付宝、淘宝等App大量采用的交互机制,解耦客户端和前端。
callback机制其实是通过传参数的方式而不是直接调用方法名,看一下小例子。
js代码
function(){
var json = {"callback": "receiveData"}
window.jsInterface.getData(JSON.stringify(json));
}
var receiveData = function(json) {
alert(JSON.stringify(json));
}
kotlin代码
@JavascriptInterface
fun getData(json: String) {
var jsJson = JSONObject(json)
var callback = jsJson.optString("callback")
var result = "服务器返回的数据"
//调用js方法必须在主线程
mWebView?.loadUrl("javascript:" + callback + "(" + result + ")")
}
这样便会形成一个闭环,H5调用Kotlin请求完数据后,在把结果返回给H5.