在Android项目开发中,如果需要在Android程序中调用web中的功能,我们可以用Jsbridge来作为桥梁进行沟通调用。
演示样例:

Jsbridge相互调用演示
Jsbridge库引入:
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
一端提供另一端调用的方法,需要使用registerHandler()方法进行注册,另一端调用的回调接收需要callHandler()方法获取回调。定义的方式需要定义一个方法名,定义接收的字符串数据,通常是定义好的json数据,然后在执行回调的方法中,使用function.callback()调用将结果数据返回给另一端。
Android部分代码:
private void initView() {
tvJs = (TextView) findViewById(R.id.tv_androidcalljs);
tvShowmsg = (TextView) findViewById(R.id.tv_showmsg);
webview = (BridgeWebView) findViewById(R.id.webview);
WebSettings webSettings = webview.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
//与js交互必须设置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
}
private void callJs(){
tvJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.callHandler("functionInJs", "Android传递给js的数据", new CallBackFunction() {
@Override
public void onCallBack(String data) {
tvShowmsg.setText(data);
}
});
}
});
}
private void registerInJs() {
webview.registerHandler("functionInAndroid", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
tvShowmsg.setText("js调用了Android");
//返回给html
function.onCallBack("Android回传给js的数据");
}
});
}
html部分代码:
<body>
<h3>html模块</h3>
<p>
<input type="button" id="enter" value="调用安卓的方法" onclick="onClick();"/>
</p>
<p>
<h3 id="showmsg"></h3>
</p>
<script>
// 注册事件监听
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
// 发送消息给Android
function onClick() {
var data = document.getElementById("showmsg").value;
window.WebViewJavascriptBridge.callHandler(
'functionInAndroid'
, {'param': "js传给Android的数据"}
, function(responseData) {
document.getElementById("showmsg").innerHTML = responseData;
}
);
}
// 在JS中注册默认的Handler
connectWebViewJavascriptBridge(function(bridge) {
//初始化
bridge.init(function(message, responseCallback) {
var data = {
'Javascript Responds': 'HelloWorld'
};
responseCallback(data);
});
//接收安卓发来的消息 并返回给安卓通知
bridge.registerHandler("functionInJs", function(data, responseCallback) {
document.getElementById("showmsg").innerHTML = data;
var responseData = "js回传给Android的数据";
responseCallback(responseData);
});
})
</script>
</body>
xml部分代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.androidusejs.MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android模块"
android:textColor="#000"
android:textStyle="bold"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_androidcalljs"
android:layout_width="170dp"
android:layout_height="30dp"
android:text="Android调用Js"
android:background="@drawable/roundsmall_bggreen"
android:gravity="center"
android:layout_marginTop="10dp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/tv_showmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:layout_marginTop="20dp"
android:textSize="20sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
对Jsbridge库进行封装处理方向
- 自定义自己的BridgeWebView类
- 简化方法的调用
- 统一处理json解析,统一的异常处理机制
Jsbridge库能跨端相互调用的依据是什么
这个库能实现 JavaScript 和 Java 的相互调用,核心是它通过自定义 URL Scheme 拦截和 WebView 的 JS 执行能力,建立了一套基于消息队列的异步通信机制。
JS 和 Native 如何沟通
这个 JsBridge 的核心,是让 JS 和 Native 能可靠地互相发送消息和处理结果。
通信的触发与拦截:
* JS 调用 Native:JS 将调用信息放入本地的 sendMessageQueue 队列,然后通过创建一个隐藏的 iframe 并将其 src 属性设置为一个特定的自定义协议 URL(例如 yy://__QUEUE_MESSAGE__/)来发出信号。
Native 拦截请求:Native 端的 BridgeWebViewClient 会通过重写 shouldOverrideUrlLoading 方法,拦截并识别此特定格式的 URL(以 yy:// 开头)。一旦识别,Native 便不会进行实际的页面跳转,而是开始处理 JS 发出的调用请求。