JSBridge连接JAVA和JS的桥梁

来源:互联网 发布:网络大电影2017 编辑:程序博客网 时间:2024/05/04 12:07

今天带来github上的一个开源库,JSBridge!
什么是JSBridge ?
其实很好理解,是一个Java和JavaScript之间的一座桥梁。
为什么要用JSBridge?
它提供了安全、方便的方式从js调用Java代码和调用js代码从Java。

效果图:
这里写图片描述

可能看效果,刚开始会有点不明白。没事,仔细看下下面的介绍,相信你会对这个库有个深入的了解,其实内容不是很多!

首先引入github上的依赖库:
app目录下的.build文件

dependencies {    compile 'com.github.lzyzsd.jsbridge:library:1.0.0'}

JS调用原生的方法,实现JS传参到原生,原生响应数据给JS。

JS中代码:

 function testClick1() {            var str1 = document.getElementById("text1").value;            var str2 = document.getElementById("text2").value;            //call native method关键方法,调用原生方法            window.WebViewJavascriptBridge.callHandler(                'submitFromWeb'//原生的方法名                , {'param': str1}//带个原生方法的参数                , function(responseData) {//响应原生回调方法                    document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData                }            );        }

原生中的方法:

//JS调用原生的方法,原生方法名与JS调用一致        webView.registerHandler("submitFromWeb", new BridgeHandler() {            @Override            public void handler(String data, CallBackFunction function) {//data是Js传来的数据,function方法是回调给Js的(带Str参数)                Log.i(TAG, "handler = submitFromWeb, data from web = " + data);//data即为JS传来的用户名                function.onCallBack("submitFromWeb exe, response data from Java");//返回给JS的数据            }        });

设置一个默认的handler,这样Js调用原生的方法时不需要声明Handler的名称

原生方法:

webView.setDefaultHandler(new DefaultHandler());

Js方法:

 function testClick() {            var str1 = document.getElementById("text1").value;            var str2 = document.getElementById("text2").value;            //send message to native            var data = "name=" + str1 + ",pass=" + str2;            window.WebViewJavascriptBridge.send(                data                , function(responseData) {                    document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData                }            );

这样Js调用原生的方法返回的响应数据,其实是DefaultHandler中实现的:

public class DefaultHandler implements BridgeHandler {    String TAG = "DefaultHandler";    public DefaultHandler() {    }    public void handler(String data, CallBackFunction function) {        if(function != null) {            function.onCallBack("DefaultHandler response data");        }    }}

感觉这个方法不是特别实用,接着往下看!

原生调用Js中的放法:

原生方法:

@Override    public void onClick(View v) {        if (button.equals(v)) {            //原生通过callHandler方法,可以调起JS中名为functionInJs的方法            webView.callHandler("functionInJs", "data from Java", new CallBackFunction() {                @Override                public void onCallBack(String data) {                    // TODO Auto-generated method stub                    //data是Js的functionInJs中返回的数据                    Log.i(TAG, "reponse data from js " + data);                }            });        }    }

JS中functionInJs的方法:

connectWebViewJavascriptBridge(function(bridge) {            bridge.init(function(message, responseCallback) {                console.log('JS got a message', message);                var data = {                    'Javascript Responds': 'Wee!'                };                console.log('JS responding with', data);                responseCallback(data);            });            //这里就是Js注册的functionInJs方法,data即为原生带来的参数            bridge.registerHandler("functionInJs", function(data, responseCallback) {                //将原生带来的参数,显示在show标签位置                document.getElementById("show").innerHTML = ("data from Java: = " + data);                var responseData = "Javascript Says Right back aka!";                //调用responseCallback方法可以带传参数到原生                responseCallback(responseData);            });        })

OK,那么上面效果默认进来的时候show标签里面的数据是哪里来的呢,其实在原生的MainActivity中还有一个地方调用了Js中注册的functionInJs方法

MainActicvity方法中,这里user是原生定义的一个对象

//将User对象传递给JS的functionInJs方法,同样会走到上面Js的functionInJs方法中  webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {            @Override            public void onCallBack(String data) {            }        });

再来看js里面选择文件上传的,调用原生的方法

js中只要声明:

<input type="file" value="打开文件" />

即可,主要工作在原生的MainActivity中执行:

webView.setWebChromeClient(new WebChromeClient() {            @SuppressWarnings("unused")            public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType, String capture) {                this.openFileChooser(uploadMsg);            }            @SuppressWarnings("unused")            public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType) {                this.openFileChooser(uploadMsg);            }            public void openFileChooser(ValueCallback<Uri> uploadMsg) {                mUploadMessage = uploadMsg;                pickFile();            }        });

pickFile()方法是原生调起本地相册

public void pickFile() {        Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT);        chooserIntent.setType("image/*");        startActivityForResult(chooserIntent, RESULT_CODE);    }

Intent实现的回调函数

@Override    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {        if (requestCode == RESULT_CODE) {            if (null == mUploadMessage){                return;            }            Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();            //这里调用该方法,将原生得到的数据返回给JS            mUploadMessage.onReceiveValue(result);            mUploadMessage = null;        }    }

ps:注意,这个lib将把WebViewJavascriptBridge 对象注入窗口对象,因此,在你的js中使用webviewJavascripBridge之前,你必须确认你的WebViewJavaScriptBridge存在,如果你的webViewJavasciptBridge不存在,你可以监听webViewJavascriptBridgeReady事件

function connectWebViewJavascriptBridge(callback) {            if (window.WebViewJavascriptBridge) {                callback(WebViewJavascriptBridge)            } else {                document.addEventListener(                    'WebViewJavascriptBridgeReady'                    , function() {                        callback(WebViewJavascriptBridge)                    },                    false                );            }        }
1 0