美文网首页
Android与js的交互方式

Android与js的交互方式

作者: 真胖大海 | 来源:发表于2020-01-08 11:27 被阅读0次

    参考
    Android:你要的WebView与 JS 交互方式 都在这里了

    代码

    一.交互方式总起

    1.1 Android调用js

     + WebView.loadUrl(“javascript:js方法名”) 
     + WebView.evaluateJavascript("javascript:js方法名")
    

    1.2 js调用Android

    + 通过WebView的addJavascriptInterface()进行对象映射
    + 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
    + 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
    

    二.Android调用js

    2.1 WebView.loadUrl

    如果js中有一个方法名为 callByAndroidLoadUrl

    function callByAndroidLoadUrl(){
           document.getElementById("demo").innerHTML = "109876"
    }
    

    则在android中使用如下代码调用

            web_view.loadUrl("javascript:callByAndroidLoadUrl()")
    

    2.2 WebView.evaluateJavascript

    如果js中有一个名为callByAndroidEvaluateJavascript

      function callByAndroidEvaluateJavascript(){
                document.getElementById("demo").innerHTML = "678910"
                return "hahaha"
            }
    

    则在android中使用如下代码调用

        /**
         * 使用WebView.evaluateJavascript调用js
         */
        fun androidInvokeJsByEvaluateJavascript(view: View) {
            web_view.evaluateJavascript("javascript:callByAndroidEvaluateJavascript()") {
                Log.i("MainActivity", it)
            }
        }
    

    2.3 总结

    调用方法 有点 缺点 使用场景
    使用loadUrl() 方便简洁 效率低;调用的方法不能有返回值,如果方法有返回值,则webview会显示返回的内容 不需要返回值
    使用WebView.evaluateJavascript 效率高 仅支持4.4以上 android4.4以上

    三.js调用android代码

    3.1 WebView的addJavascriptInterface()对象映射

    比如 android有一个类InvokeByJs这个类,其中showMsg需要被js调用,则

    
        inner class InvokeByJS {
            // 被JS调用的方法必须加入@JavascriptInterface注解
            @JavascriptInterface
            fun showMsg(msg: String) {
                Toast.makeText(this@MainActivity, msg, Toast.LENGTH_LONG).show()
            }
        }
       
       //将InvokeByJS类对象映射到js的invokeByJS对象
      web_view.addJavascriptInterface(InvokeByJS(), "invokeByJS")
    

    js中

    <button type="button" onclick="callAndroidByObjectMap()">点击 通过对象映射调动android代码</button>
    
    <script>
     function callAndroidByObjectMap(){
                invokeByJS.showMsg("js调用了android中的hello方法");
             }
    
    </script>
    

    3.2 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url

    js代码

    <button type="button" onclick="callAndroidByLoadUrl()">点击 通过重载url调动android代码</button>
    
    function callAndroidByLoadUrl(){
                  document.location = "js://tosat?msg=需要android处理的url";
    }
    
    

    android代码

          //拦截url
            web_view.webViewClient = object : WebViewClient() {
    
                @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
                override fun shouldOverrideUrlLoading(
                    view: WebView?,
                    request: WebResourceRequest?
                ): Boolean {
    
                    val url = request?.url.toString()
                    if (url.startsWith("js://tosat")) {
                        //得到的url是通过url编码的,所以这里需要url解码
                        val msg =URLDecoder.decode(url).split("msg=")[1]
                        Toast.makeText(this@MainActivity, (msg), Toast.LENGTH_LONG).show()
                        return true
                    }
    
                    return false
                }
            }
    

    3.3 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

    以prompt为例
    prompt为一个输入框。

    html中prompt调用的输入框

    我们可以通过拦截对话框,进行处理。
    html中

    <button type="button" onclick="clickPrompt()">点击 通过Prompt调动android代码</button>
    
     function clickPrompt(){
             var result=prompt("js://tosat?msg=通过prompt调用android");
          }
    

    android代码

            web_view.webChromeClient = object :WebChromeClient(){
                override fun onJsPrompt(
                    view: WebView?,
                    url: String,
                    message: String,
                    defaultValue: String?,
                    result: JsPromptResult
                ): Boolean {
                    if(message.startsWith("js://tosat")){
                        val msg =message.split("msg=")[1]
                        Toast.makeText(this@MainActivity, (msg), Toast.LENGTH_LONG).show()
                        //result.confirm必须要赋值,表示prompt的返回值
                        result.confirm("js调用了Android的方法成功啦")
                       //返回true,表示WebChromeClient会处理prompt,WebView不需要弹出输入框
                        return true
                    }
                    return super.onJsPrompt(view, url, message, defaultValue, result)
                }
            }
    

    3.4总结

    调用方法 有点 缺点 使用场景
    addJavascriptInterface() 方便简洁;有返回值 Android4.2存在漏洞 Android4.2以上
    WebViewClient 的shouldOverrideUrlLoading () 无漏洞 需要自定定义协议;无返回值 不需要返回值
    通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息 无漏洞;有返回值 需要自定定义协议 大多数情况下

    相关文章

      网友评论

          本文标题:Android与js的交互方式

          本文链接:https://www.haomeiwen.com/subject/tubjactx.html