美文网首页
WebView交互架构项目实战(二):JS与Java交互

WebView交互架构项目实战(二):JS与Java交互

作者: bug音音 | 来源:发表于2021-01-18 17:27 被阅读0次

    前言

    这篇中主要介绍Java与本地的Html 中的JS进行交互。

    步骤

    • 在布局文件中添加WebView控件。
    • 获取到WebView实例。
    • 调用setJavaScriptEnabled(true)方法设置支持JS。
    • 调用addJavascriptInterface(Object object, String name) 方法加载javascript中的调用方法。
    • 调用loadUrl(String url)方法加载本地的Html。
      说明:加载本地的Html文件时,url 为 file:///android_asset/ + htmlname.html。 eg:mWebView.loadUrl("file:///android_asset/index.html");

    API说明

    addJavascriptInterface(Object object, String name)

    参数说明:

    第一个参数是一个包含html页面中调用方法的类.
    第二个参数是调用类时的标记.

    Javascript中调用Java 的规则:

    Html中结构:

    • javascript: + name + . + method

    说明:

    • javascript:是不变的,不要忘记冒号。
    • name:是在调用 addJavascriptInterface(Object object, String name)方法中设置的name,二者要保持对应。method:是调用的方法,method即调用方法中的方法名字。
      eg:Java中有call 方法,在Html中js中
      <a href='javascript:contact.call()'>拨打</a>,点击拨打便会调用Java 中的call 方法。
    Java 中调用 Javascript 的规则:

    Java中结构:
    mWebView.loadUrl("javascript: + methodName('" + data + "')");
    在此结构中只有methodName和data是变量,其他都为不可变的,照用即可。

    • methodName:是指Javascript中的方法
    • data:是指传入的数据。
    在实际使用时重要注意问题
    • Android 4.2以后要加注释语句@JavascriptInterface
      在Android 4.2之前向webview注入的对象所暴露的接口没有注释语句@JavascriptInterface,而4.2及以后的则多了注释语句@JavascriptInterface

    经过查官方文档所知,因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加.

    • 在Android 较高版本中调用JavaScript 中方法的语句要在线程中运行。
    // 调用javascript中的show()方法
    mHandler.post(new Runnable() {
        @Override
        public void run() {
            mWebView.loadUrl("javascript:show('" + json + "')");
        }
    });
    
    

    示例代码:

    html 代码:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <script type="text/javascript">
       function show(jsondata){
          //[{name:"xxx",amount:600,phone:"13988888"},{name:"bb",amount:200,phone:"1398788"}]
               var jsonobjs = eval(jsondata);
               var table = document.getElementById("personTable");
               for(var y=0; y<jsonobjs.length; y++){
                  var tr = table.insertRow(table.rows.length); //添加一行
                  //添加三列
                  var td1 = tr.insertCell(0);
                  var td2 = tr.insertCell(1);
                  td2.align = "center";
                  var td3 = tr.insertCell(2);
                  td3.align = "center";
                  //设置列内容和属性
                  td1.innerHTML = jsonobjs[y].name; 
                  td2.innerHTML = jsonobjs[y].amount; 
                  td3.innerHTML = "<a href='javascript:contact.call(\""+ jsonobjs[y].phone+ "\")'>"+ jsonobjs[y].phone+ "</a>"; 
             }
       }
    </script>
    </head>
    <!-- js代码通过webView调用其插件中的java代码 -->
    <body onload="javascript:contact.showContacts()">
       <table border="0" width="100%" id="personTable" cellspacing="0">
          <tr>
             <td width="35%">姓名</td><td width="30%" align="center">存款</td><td align="center">电话</td>
          </tr>
       </table>
       <a href="javascript:window.location.reload()">刷新</a>
    </body>
    </html>
    
    
    Java代码:
    public class MainActivity extends AppCompatActivity {
    
        private WebView mWebView;
    
        private Handler mHandler = new Handler();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mWebView = (WebView) findViewById(R.id.web_view);
            mWebView.loadUrl("file:///android_asset/index.html");
            mWebView.getSettings().setJavaScriptEnabled(true);
    
            mWebView.addJavascriptInterface(new JSObject(),"contact");
    
        }
    
        public class JSObject{
            @JavascriptInterface
            public void call(String phone){
                Log.e("phone", "phone---->" + phone);
            }
    
            @JavascriptInterface
            public void showContacts(){
                try {
                    JSONArray jsonArray = new JSONArray();
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("name", "zhangsan");
                    jsonObject.put("amount", "50");
                    jsonObject.put("phone", "123465798");
                    jsonArray.put(jsonObject);
    
                    JSONObject jsonObject1 = new JSONObject();
                    jsonObject1.put("name", "lisi");
                    jsonObject1.put("amount", "48");
                    jsonObject1.put("phone", "987456123");
                    jsonArray.put(jsonObject1);
    
                    final String json = jsonArray.toString();
                    // 调用javascript中的show()方法
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mWebView.loadUrl("javascript:show('" + json + "')");
                        }
                    });
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:WebView交互架构项目实战(二):JS与Java交互

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