Android、JS交互

本文介绍了在Hybrid APP开发中,Android与JavaScript交互的方式。通过WebView组件,Android可以调用JavaScript,反之亦然。详细讲解了两种Android调用JavaScript的方法,包括使用loadUrl和evaluateJavascript,以及JavaScript调用Android的三种方法,涉及@JavascriptInterface注解的使用。
摘要由CSDN通过智能技术生成
顺应大前端的潮流,Hybrid APP越来越重要,学习一波Android与JavaScript的交互方式。

原理:通过WebView这个中间组件来相互调用

一些基础的配置:

val webSetting = webView.settings
 // 允许与JS交互
webSetting.javaScriptEnabled = true
// 允许弹窗
webSetting.javaScriptCanOpenWindowsAutomatically = true
//  loadUrl会使页面刷新
//  先载入JS代码
//  格式规定为:file:///android_asset/文件名.html
webView.loadUrl("file:///android_asset/javascript.html")

1.Android调用JavaScript

  • 通过WebView.loadUrl("javascript:callJSByLoadUrl()"): javascript为文件名,callJSByLoadUrl为对应文件下的对应方法名
  • 通过WebView.evaluateJavascript("javascript:callJSByLoadUrl()"): javascript为文件名,callJSByLoadUrl为对应文件下的对应方法名

方式一:

webView.post {
                // 调用javascript的callJS()方法
                webView.loadUrl("javascript:callJSByLoadUrl()")
            }

方式二:

 webView.post {
                //  方式二: 4.4以上才可使用
                webView.evaluateJavascript(
                    "javascript:callJSByEvaluate()"
                ) { value ->
                    Log.e("wdl", "evaluateJavascript   $value")
                }
            }

对应的JS文件如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Wdl</title>

    <script>
   function callJSByLoadUrl(){
      alert("Android调用了JS的callJSByLoadUrl方法");
   }

     function callJSByEvaluate(){
      alert("Android调用了JS的callJSByEvaluate方法");
   }

    </script>

</head>

</html>

两种方式的不同点:
1.通过loadUrl方法,会导致整个页面刷新(4.4以下使用)
2.通过evaluateJavascript方法(4.4以上使用)

2.JavaScript调用Android

  • 通过webView.addJavascriptInterface(JS2Android(), "test"): JS2Android()为JS与Android的映射类,test为映射对象的名称
  • 通过WebViewClient.shouldOverrideUrlLoading拦截url,解析url调用相对应的方法
  • 通过WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

方式一:

对应的映射类:加上 @JavascriptInterface 注解,方法名即JS中使用的方法名

class JS2Android {

    @JavascriptInterface
    public fun hello(msg: String) {
        Log.e("wdl", "hello $msg")
    }
}
 // 方式一:addJavascriptInterface()
        // 将Java对象映射到JS对象
        // 参数一:JS2Android
        // 参数二:对象名
        // 存在严重的漏洞问题
        webView.addJavascriptInterface(JS2Android(), "test")

方式二:

 // 方式二:通过WebViewClient.shouldOverrideUrlLoading拦截url,解析url调用相对应的方法
        // 复写WebViewClient类的shouldOverrideUrlLoading方法
        // 获取Android 返回的参数比较复杂
        // 如果JS想要得到Android方法的返回值,只能通过 WebView 的 loadUrl ()去执行 JS 方法把返回值传递回去,相关的代码如下:
        // // Android:MainActivity.java
        //mWebView.loadUrl("javascript:returnResult(" + result + ")");
        //
         JS:javascript.html
        //function returnResult(result){
        //    alert("result is" + result);
        //}
        webView.webViewClient = object : WebViewClient() {
            @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                val uri = request?.url
                // js://webview?arg1=111&arg2=222      示例uri
                // 获取 uri 并进行解析
                if (uri?.scheme.equals("js")) {
                    if (uri?.authority.equals("webview")) {

                        // 获取参数
                        val params = uri?.queryParameterNames

                        // 调用相对应的Android 方法
                        Log.e("wdl", "shouldOverrideUrlLoading拦截url ${params?.size}")

                    }
                    return true
                }
                return super.shouldOverrideUrlLoading(view, request)
            }
        }

方式三:

// 方式三:通过WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
        webView.webChromeClient = object : WebChromeClient() {
            // 输入框
            override fun onJsPrompt(
                view: WebView?,
                url: String?, // file:///android_asset/javascript1.html,不是我们所需的
                message: String?,
                defaultValue: String?,
                result: JsPromptResult?
            ): Boolean {
                val uri = Uri.parse(message)
                if (uri?.scheme.equals("js")) {
                    if (uri?.authority.equals("webview")) {

                        // 获取参数
                        //val params = uri?.queryParameterNames

                        // 调用相对应的Android 方法
                        //Log.e("wdl", "通过WebChromeClient ${params?.size}")

                        // result?.confirm("JS通过WebChromeClient调用Android方法成功了!!")
                        result?.confirm("调用Android方法成功了")

                    }
                    return true
                }

                return super.onJsPrompt(view, url, message, defaultValue, result)
            }

            // 确认框
            override fun onJsConfirm(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
                return super.onJsConfirm(view, url, message, result)
            }

            // 警告框
            override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
                return super.onJsAlert(view, url, message, result)
            }
        }

    }

对应的JS文件:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Wdl</title>
    <script>

         function callAndroidByAddJavascriptInterface(){
            // 由于对象映射,所以调用test对象等于调用Android映射的对象
            test.hello("AddJavascriptInterface js调用了android中的hello方法");
         }

          function callAndroidByShouldOverrideUrlLoading(){
            // 拦截url。。解析并调用对应的方法
            /*约定的url协议为:js://webview?arg1=111&arg2=222*/
            document.location = "js://webview?arg1=111&arg2=222";
         }

          function callAndroidByWebChromeClient(){
            // 通过WebChromeClient
            /*约定的url协议为:js://webview?arg1=111&arg2=222*/
            var result = prompt("js://webview?arg1=111&arg2=222")
            alert("返回值"+result)
         }



    </script>
</head>
<body>
<button type="button" id="button1" onclick="callAndroidByAddJavascriptInterface()">callAndroidByAddJavascriptInterface
</button>
<button type="button" id="button2" onclick="callAndroidByShouldOverrideUrlLoading()">
    callAndroidByShouldOverrideUrlLoading
</button>

<button type="button" id="button3" onclick="callAndroidByWebChromeClient()">callAndroidByWebChromeClient
</button>
</body>
</html>

本篇文章相对来说比较简单…,…!!!

参考自:https://blog.csdn.net/carson_ho/article/details/64904691

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>