Android关于JavaScript与Native方法相互调用

 前段时间,阿里的去啊App 5.1.1发布了,这轮发布的热点就是Hybrid混合框架搞定了H5的“无缝秒出”。伴随着H5的发展,Native+HTML5的混合开发模式已经成 为一种潮流,著名的框架比如FaceBook的React Native,AngularJS,最近微信发布的应用号也是为混合开发填了一把火。我最近研究了一下关于Native和HTML混合开发的一些基础知 识,特发文于一文,与大家分享一下成果。

      首先是在布局文件建WebView,并在Activity中获取实例,不赘述。以下为MainActivity代码:

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);
        // 添加一个对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法
        webView.addJavascriptInterface(new Contact(this, webView), "contact");
        webView.getSettings().setDomStorageEnabled(true);// H5页面,开启Dom缓存
        webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        //从网络加载HTML
        webView.loadUrl("http://192.168.4.252:8080/JS_NativeDemo/index.html");
        //加载本地HTML
//        webView.loadUrl("file:///android_asset/index.html");
    }

}
这段代码的作用主要是为webView对象允许JavaScript的执行,并将自己的脚本对象传递给webView,contact对象的具体作用可查看index.html源码中的调用过程。
       注意此处是使用web的html界面,需要添加网络请求的相关权限:
       <uses-permission  android :name= "android.permission.INTERNET" />

Contact对象的代码如下:
public class Contact {

    private Activity activity;
    private WebView webView;

    public Contact(Activity activity, WebView webView) {
        this.activity = activity;
        this.webView = webView;
    }

    //JavaScript调用此方法拨打电话
    @JavascriptInterface
    public void call(String phone) {
//            startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone)));
        Toast.makeText(activity, phone, Toast.LENGTH_LONG).show();
    }

    //Html调用此方法传递数据
    @JavascriptInterface
    public void showcontacts() {
        handler.sendEmptyMessage(0);
    }

    @JavascriptInterface
    public void toast(String str) {
        Toast.makeText(activity, "aaaaaaaaaaaa  --- " + str, Toast.LENGTH_LONG).show();
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    String json = "[{\"name\":\"zxx\", \"amount\":\"9999999\", \"phone\":\"18600012345\"}]";
                    // 调用JS中的方法
                    webView.loadUrl("javascript:show('" + json + "')");
                    break;
                default:
                    break;
            }
        }
    };

    // 重写addJavaScriptInteface getClass方法,防止类对象漏洞攻击
    public Object getClass(Object o) {
        return null;
    }

}
    getClass(Object o)方法是一个重写方法,是为了修补Android 4.2(API17)之前的javaScrip脚本注入添加的。然后每个定义在这个类中的要被HTML页面调用的方法都要加上@JavascriptInterface注解。此处需要注意的是showcontacts()方法触发的Javascript脚本涉及了界面绘制,因此必须要在主线程中调用,此处使用了Handler来解决这个问题。
    关键的index.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){
                    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 οnlοad="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>
javascript:contact.showcontacts()、javascript:contact.toast('123')调用了MainActivity中contact对象的方法。而
webView.loadUrl("javascript:show('" + json + "')")一句则调用了index.html中的JavaScript脚本。虽然例子中的实现的功能非常简单,但是这种混合的交互方式可以为开发者解决很多开发中的限制。
      另外,index.html文件可以放到Android的assets目录下,实现本地调用。

如文章有错漏或demo有BUG,欢迎指正,求教育,求教导~~~

源码下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值