zoukankan      html  css  js  c++  java
  • android与JS函数传参遗留问题

     //当页面加载完成后,调用js方法   //                    
    
                   JSONObject json = new JSONObject();
                   json.put("name", "安卓");
                   json.put("city", "北京");
                   mWebview.loadUrl("javascript:showMessage("+json.toString()+")");

    Android将JSON数据给JS,  JS函数之间传参???

    当你需要传入的字符串为"1234556789"这样全部为数字的字符串时,这样写一点问题没有:

    mWebview.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    String data = "123456789";
                    mWebview.loadUrl("javascript:setData(" + data + ")");
                    super.onPageFinished(view, url);
                }
            });

    但是一般情况下不会是这样的,多数情况下js需要我们传入的是一个json类型的字符串,这时需要在你的变量两边加上一对单引号,否则是传不过去的,憋了我2天啊。

     

     mWebview.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
     
            //参数一
            String data = "{"code": "12","id": "4","name": "浮标3","position": {"cartographicDegrees": [117.158944444, 39.16886111, 0.0]}"; 
            //参数二
            String res = "maxwindSpeed";
     
            //单个参数传递
            mWebview.loadUrl("javascript:setData('" + data + "')");  //仔细看我给标红的单引号
     
            //多个参数传递,现在是两个的,只需要把你需要传入的参数外面套上一个单引号,自己找精华吧
           mWebview.loadUrl("javascript:setData('" + data  + "','" + res  +"')");
        }
    });

     

    js调用Android

    private class JsCallAndroid{
        @JavascriptInterface
        public void jsCallbackMethod(String result) {
            LogUtils.d("js接收到的字符串为:" + result);  //当js中的方法被调用的时候打印接收到的字符串
        }
    function setData(str,icon){
    window.jsCallAndroid.jsCallbackMethod(str);        //调用这个方法就会回调上面的方法,打印接收到的字符串
    var res = JSON.parse(str);
             ...
             ...
    }

     

     

    这里还有一篇关于优化的  Android-Java和HTML5交互-混合开发-优化

    其实webview加载资源的速度并不慢,但是如果资源多了,当然就很慢。图片、css 、js 、html这些资源每个大概需要10-200ms ,一般都是30ms就ok了。不过webview是必须等到全部资源都完成加载,才会进行渲染的,所以加载的速度很重要!从Google上我们了解到,webview加载页面的顺序是:先加载html,然后从里面解析出css、js文件和页面上的图片资源进行加载。如果webkit的缓存里面有,就不加载。加载完这些资源之后,就进行css的渲染和js的执行。CSS的渲染一般不需要很长时间,几十毫秒就ok。关键是js的执行,如果用了jQuery,则执行起来需要5-6秒。而在这段时间,如果不在webview里设置背景,网页部分是白色的,很难看。这是一个很糟糕的用户体验。所以建议如果用网页布局程序,最好别用那些庞大的js框架。最好使用原生的js写业务脚本,以提升加载速度,改善用户体验。

    在Android上怎样实现JAVA和JS交互呢?

    Android的webview是基于webkit内核的,webview中集成了js与java互调的接口函数,通过addJavas criptInterface方法,可以将Java的类注册进webkit,给网页上的js进行调用,而且还可以通过loadUrl方法给webkit传递一个URL,供浏览器来进行解析,实现Java和js交互。

    要想运行网页上的js脚本,webview必须设置支持Javas cript。

    Java代码:1mWebview.getSettings().setJavascriptEnabled(true);

    然后是设置webView要加载的网页:

      web的网页:webView.loadUrl("http://www.google.com");

      本地的网页:webView.loadUrl("file:///android_asset/XX.html"); //本地的存放在:assets文件夹中

    webview做完基本的初始化后我们还要要给它,加进一个回调的代理类JavascriptInterface,并给它一个调用的名称:ncp

    Java代码:1mWebView.addJavas criptInterface(new Javas criptInterface(),"ncp");

    Javas criptInterface可以是一个普通的Java类,类实现的方法,均可被js回调:

    Java代码:

    final class Javas criptInterface {

      public int callOnJs() {

        return 1000;

      }

      public void callOnJs2(String mode) {

        //TODO

      }

    }

    Java要调用js的方法,只需知道js的方法名称即可:

      Java代码:1mWebView.loadUrl("javas cript:onSaveCallback()");

    js 这边就更简单(存在的版本兼容问题,参考使用WebView过程中的问题总结):

      JS代码:  

    window.onload = function(){

      document.getElementById('btn_1').addEventListener('click', onBtnClick, false);

      var _int_value = window.ncp.callOnJs();

      alert("get int from java:" + _int_value );

    }

    function onBtnClick() {

      window.ncp.callOnJs2("click");

    }

    Java和js交互有以下一些特点:

    1.Java 调用 js 里面的函数,速度并不令人满意,大概一次一两百毫秒吧,如果要做交互性很强的事情,这种速度会让人疯掉的。而反过来就不一样了, js 去调 java 的方法,速度很快,基本上 40-50 毫秒一次。所以尽量用 js 调用 java 方法,而不是 java 去调用 js 函数。

    2.Java 调用 js 的函数,没有返回值,而 Js 调用 java 方法,可以有返回值。返回值可以是基本类型、字符串,也可以是对象。如果是字符串,有个很讨厌的问题,第 3 点我会讲的。如果是对象,这个对象会被转换为 js 的对象,直接可以访问里面的方法。但是我不推荐 java 返回给 js 的是对象,除非是必须。因为 js 收到 java 返回的对象,会产生一些交换对象,而如果这些对象的数量增加到了 500 或 600 以上,程序就会出问题。所以尽量返回基本数据类型或者字符串。

    3.Js 调用 Java 的方法,返回值如果是字符串,你会发现这个字符串是 native 的,不能对它进行一些修改操作,比如想对它 substr ,取不到。怎么解决呢?转成 locale 的。使用 toLocaleString() 函数就可以了。不过这个函数的速度并不快,转化的字符串如果很多,将会很耗费时间。

    下面是一个具体的例子:

    1.新建assets文件夹,将本地html页面拷贝到该文件夹下。

    package com.example.webview_workflowy;  
      
    import android.app.Activity;  
    import android.content.Intent;  
    import android.net.Uri;  
    import android.os.Bundle;  
    import android.webkit.WebView;  
    import android.widget.Toast;  
      
    public class MainActivity extends Activity {  
      
        private WebView webView;  
      
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            //加载页面  
            webView = (WebView) findViewById(R.id.webview);  
            //允许JavaScript执行  
            webView.getSettings().setJavaScriptEnabled(true);  
            //找到Html文件,也可以用网络上的文件  
            webView.loadUrl("file:///android_asset/index.html");  
            // 添加一个对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法  
            webView.addJavascriptInterface(new Contact(), "contact");  
        }  
      
        private final class Contact {  
            //JavaScript调用此方法拨打电话  
            public void call(String phone) {  
    //            startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone)));  
                Toast.makeText(MainActivity.this, phone, Toast.LENGTH_LONG).show();  
            }  
      
            //Html调用此方法传递数据  
            public void showcontacts() {  
                String json = "[{"name":"zxx", "amount":"9999999", "phone":"18600012345"}]";   
                // 调用JS中的方法  
                webView.loadUrl("javascript:show('" + json + "')");  
            }  
              
            public void toast(String str){  
                Toast.makeText(MainActivity.this, "aaaaaaaaaaaa  --- " + str, Toast.LENGTH_LONG).show();  
            }  
        }  
      
    }
    <!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){              
                        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>  
        <body onload="javascript:contact.showcontacts()">  
           <button id="button" onclick = "javascript:contact.toast('123')">haha</button>  
           <table border="0" width="100%" id="personTable" cellspacing="0">  
                <tr>  
                    <td width="30%">姓名</td>  
                    <td width="30%" align="center">存款</td>  
                    <td align="center">电话</td>  
                </tr>  
            </table>  
        </body>  
    </html>
  • 相关阅读:
    mysql limit
    random.nextint()
    “MSDTC 事务的导入失败: Result Code = 0x8004d00e。
    JUnit-4.11使用报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing错误
    iOS ERROR: unable to get the receiver data from the DB 解决方式
    STL algorithm算法mov,move_backward(38)
    看 《一次谷歌面试趣事》 后感
    C++胜者树
    拿年终奖前跳槽,你才是赢家!
    日期字符串格式化成日期/日期格式化成指定格式字符串
  • 原文地址:https://www.cnblogs.com/ation/p/12145951.html
Copyright © 2011-2022 走看看