先来说说什么是JS交互:
说的俗一点就是通过我们项目中的控件来调用HTML里的JS代码,也可以通过JS来调用项目中的代码。
Android与JS之间的桥梁就是WebView了,我们是通过WebView来实现他们的相互调用。
Android调用Js代码:
Android调用Js代码有两种方式
Js调用Android代码:
Js调用Android代码有三种方式
JS写的Html:
Android与Js交互
//JS的代码
在这里改变代码
布局文件:
android代码:
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val webview = findViewById(R.id.android_web)
webview.settings.javaScriptEnabled = true //设置WebView可以与JS交互 这里必须设置
webview.settings.javaScriptCanOpenWindowsAutomatically = true //设置允许JS中的弹窗
webview.loadUrl("file:///android_asset/web1.html")
val android_btn = findViewById
使用这个方法不会重新刷新webView,而loadUrl会触发刷新,且这个方法必须要在Android4.4以上才可以使用
使用方式:
1.将minSdkVersion最低版本改为19
build.gradle----minSdkVersion
2.直接替换第一种方式
webview.evaluateJavascript("javascript:clickJS()",object :
ValueCallback {
override fun onReceiveValue(value: String?) {
// 这里返回JS的结果
}
})
两种方式的区别:
根据情况使用两种方式,我们可以根据当前项目开发的需求选择相应的使用方式
我们可以直接判断版本号来区分使用方式
if (Build.VERSION.SDK_INT< 18) {
android_web.loadUrl("javascript:clickJS()")
} else {
android_web.evaluateJavascript("javascript:clickJS()") {
//返回JS方法中的返回值,我们没有写返回值所以为null
}
}
JS代码:
Android代码:
webview.addJavascriptInterface(JsObject(),"android")
inner class JsObject {
@JavascriptInterface
fun jsAndroid(msg : String){
//点击html的Button调用Android的Toast代码
//我这里让Toast居中显示了
val makeText = Toast.makeText(this@MainActivity2, msg,Toast.LENGTH_LONG)
makeText.setGravity(Gravity.CENTER,0,0)
makeText.show()
}
}
来看看效果图:
使用这个方式需要定义一个协议进行拦截:
Android代码:
webview.webViewClient = MyWebViewClient()
inner class MyWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
// 获取Uri 这里的URL是我们在JS方法中写的URL协议"js://webview?name=zhangsan&age=20&sex=0"
val uri = Uri.parse(url)
if (uri.scheme == "js") {
if (uri.authority == "webview") {
val makeText = Toast.makeText(this@MainActivity, url, Toast.LENGTH_LONG)
makeText.setGravity(Gravity.CENTER, 0, 0)
makeText.show()
}
return true
}
return super.shouldOverrideUrlLoading(view, url)
}
}
来看一下效果:
JS代码:
Title
欢迎光临启舰的blog
Android代码:
class MainActivity : AppCompatActivity() {
var mWebView:WebView?=null
inner class MyWebChromeClient:WebChromeClient(){
override fun onJsAlert(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
Log.d("luojie","$message + $result")
return super.onJsAlert(view, url, message, result)
}
override fun onJsPrompt(
view: WebView?,
url: String?,
message: String?,
defaultValue: String?,
result: JsPromptResult?
): Boolean {
Log.d("luojie","$message + $result")
return super.onJsPrompt(view, url, message, defaultValue, result)
}
override fun onJsConfirm(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
Log.d("luojie","$message + $result")
return super.onJsConfirm(view, url, message, result)
}
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
Log.d("luojie","${consoleMessage?.message()}")
return super.onConsoleMessage(consoleMessage)
}
override fun onProgressChanged(view: WebView?, newProgress: Int) {
Log.d("luojie","${newProgress}")
super.onProgressChanged(view, newProgress)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mWebView = findViewById(R.id.webview)
mWebView?.settings?.javaScriptEnabled = true
mWebView?.webViewClient = WebViewClient()
mWebView?.webChromeClient = MyWebChromeClient()
mWebView?.loadUrl("file:///android_asset/web.html")
}
}
Android应用开发的时候可能会用到WebView这个组件,使用过程中可能会接触到WebViewClient与WebChromeClient,那么这两个类到底有什么不同呢?
WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:
onLoadResource |
onPageStart |
onPageFinish |
onReceiveError |
onReceivedHttpAuthRequest |
WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如
onCloseWindow(关闭WebView) |
onCreateWindow() |
onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出) |
onJsPrompt |
onJsConfirm |
onProgressChanged |
onReceivedIcon |
onReceivedTitle |
看上去他们有很多不同,实际使用的话,如果你的WebView只是用来处理一些html的页面内容,只用WebViewClient就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient。