先来说说什么是JS交互:
说的俗一点就是通过我们项目中的控件来调用HTML里的JS代码,也可以通过JS来调用项目中的代码。
Android与JS之间的桥梁就是WebView了,我们是通过WebView来实现他们的相互调用。
Android调用Js代码:
Android调用Js代码有两种方式
Js调用Android代码:
Js调用Android代码有三种方式
JS写的Html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Android与Js交互</title>
</head>
<body>
//JS的代码
<script type="text/javascript">
//无参方法
function clickJS(){
document.getElementById("zi").innerHTML = "Android调用了JS代码"
}
//有参方法
function clickJSTwo(x){
document.getElementById("zi").innerHTML = x
}
//与Android交互的方法
function clickAndroid(){
var result = prompt("js://webview?arg1=111&arg2=222")
alert("demo" + result)
}
</script>
<button type="button" onclick="clickAndroid()">我是一个按钮</button>
<p id="zi">在这里改变代码</p>
</body>
<script type="text/javascript">
function clickAndroid(){
//用androids.调用映射的对象 这里的androids是addJavascriptInterface()的第二个参数
androids.jsAndroid("我是JS,我调用了Android的方法")
}
</script>
</html>
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/android_js"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:text="调用JS代码"
android:id="@+id/android_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<WebView
android:id="@+id/android_web"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</WebView>
</LinearLayout>
android代码:
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val webview = findViewById<WebView>(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<Button>(R.id.android_btn)
android_btn.setOnClickListener {
webview.post {
kotlin.run {
//第一种方法 通过loadUrl调用JS代码
//调用无参JS方法
webview.loadUrl("javascript:clickJS()")
//调用有参JS方法
// androidWeb.loadUrl("javascript:clickJS('我调用了JS的方法')")
}
}
}
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/252a591cb25c4c6ba034eef1cca7c27d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5L2O6LCD5Ye95pWw,size_13,color_FFFFFF,t_70,g_se,x_16
使用这个方法不会重新刷新webView,而loadUrl会触发刷新,且这个方法必须要在Android4.4以上才可以使用
使用方式:
1.将minSdkVersion最低版本改为19
build.gradle----minSdkVersion
2.直接替换第一种方式
webview.evaluateJavascript("javascript:clickJS()",object :
ValueCallback<String> {
override fun onReceiveValue(value: String?) {
// 这里返回JS的结果
}
})
两种方式的区别:
1.loadUrl() 使用起来方便简洁。 但是他是在没有返回的情况下使用。 效率比较低,获取返回值的时候很麻烦。 并且调用的时候会刷新WebView
2.evaluateJavascript () 效率比loadUrl ()高很多 虽然效率高但是只支持Android4.4以上 在获取返回值时候很方便 调用时候不刷新WebView
根据情况使用两种方式,我们可以根据当前项目开发的需求选择相应的使用方式
我们可以直接判断版本号来区分使用方式
if (Build.VERSION.SDK_INT< 18) {
android_web.loadUrl("javascript:clickJS()")
} else {
android_web.evaluateJavascript("javascript:clickJS()") {
//返回JS方法中的返回值,我们没有写返回值所以为null
}
}
JS代码:
<script type="text/javascript">
function clickAndroid(){
//用androids.调用映射的对象 这里的androids是addJavascriptInterface()的第二个参数
androids.jsAndroid("我是JS,我调用了Android的方法")
}
</script>
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()
}
}
.
使用这个方式需要定义一个协议进行拦截:
<script type="text/javascript">
function clickAndroid(){
//定义url协议
document.location = "js://webview?name=zhangsan&age=20&sex=0"
}
</script>
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代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 id="h">欢迎光临启舰的blog</h1>
<button onclick="confirm('确认')">confirm</button>
<button onclick="alert('弹窗')">alert</button>
<button onclick="prompt('prompt')">prompt</button>
<button onclick="log()">log</button>
</body>
<script type="text/javascript">
function log(){
console.log("console.log");
console.warn("warnning");
console.error("error");
}
</script>
</html>
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")
}
}