JSBridge实现Android和H5交互
- 前言
- 添加JSBridge库
- 代码实现
- AndroidManifest.xml
- activity_main.xml
- javascript.html
- MainActivity.java
- 效果图
前言
相比于WebView的自带的JavascriptInterface的接口,使用JSBridge实现Android和H5之间的交互会更加方便和安全,接下来介绍一下JSBridge的具体用法。
添加JSBridge库
在Android Studio的app/build.gradle添加如下配置,即可完成JSBridge库导入:
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
}
代码实现
接下来通过示例代码演示如何实现JS和Android之间的交互
AndroidManifest.xml
AndroidManifest.xml需要加入INTERNET权限:
<uses-permission android:name="android.permission.INTERNET" />
activity_main.xml
在activity_main.xml添加JSBridge的webView:
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/activity_web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
javascript.html
创建assets目录,并在assets目录下添加JS文件,这里命名为javascript.html。在javascript.html注册供Android调用的方法,并在点击按钮时调用Android注册的方法,实现交互,具体代码如下(实际项目中H5页面往往部署在服务器上,这个使用本地JS文件方便测试):
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>JSBridge测试</title>
<script>
//注册事件监听
function connectWebViewJavascriptBridge(callback) {
if(window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge);
} else {
document.addEventListener (
"WebViewJavascriptBridgeReady",
function() {
callback(WebViewJavascriptBridge);
},
false
);
}
}
connectWebViewJavascriptBridge(function(bridge) {
//注册回调函数,接收Android端用send方法发送的消息
bridge.init(function(message, responseCallback) {
alert("message from Java = " + message);
var responseData = "Received!";
responseCallback(responseData);
});
//注册回调函数,供Android调用,接收Android端发送的数据
bridge.registerHandler("functionInJs", function(data, responseCallback) {
alert("data from Java = " + data);
var responseData = "Received!";
responseCallback(responseData);
});
})
function queryInfo(key) {
//调用Android端注册的getInformation方法进行数据查询
window.WebViewJavascriptBridge.callHandler("getInfomation", key,
function(responseData) {
alert("responseData from Java = " + responseData);
});
}
function control(key) {
//调用Android端注册的controlDevice方法进行设备状态控制
window.WebViewJavascriptBridge.callHandler("controlDevice", key,
function(responseData) {
alert("responseData from Java = " + responseData);
});
}
function sendMessage(message) {
//通过send方法向Android发送消息
window.WebViewJavascriptBridge.send(message, function(responseData) {
alert("responseData from Java = " + responseData);
});
}
</script>
</head>
<body>
<p>JSBridge测试</p>
<p><input type="button" value="查询设备类型" onclick='queryInfo("deviceType");'/></p>
<p><input type="button" value="查询设备状态" onclick='queryInfo("deviceStatus");'/></p>
<p><input type="button" value="打开设备" onclick='control("open");'/></p>
<p><input type="button" value="关闭设备" onclick='control("close");'/></p>
<p><input type="button" value="发送消息" onclick='sendMessage("Hello Android!");'/></p>
</body>
</html>
MainActivity.java
在MainActivity.java中加载创建好的javascript.html,注册供JS调用的方法,并在启动时调用JS注册的方法发送消息和数据:
package com.example.testjsbridge;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebChromeClient;
import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.BridgeWebViewClient;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.github.lzyzsd.jsbridge.DefaultHandler;
public class MainActivity extends Activity {
BridgeWebView mWebView;
String deviceType = "插座";
boolean deviceStatus = false;
String myData = "{data,1234567890}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (BridgeWebView) findViewById(R.id.activity_web_view);
initWebView();
}
private void initWebView() {
mWebView.setWebViewClient(new MyWebViewClient(mWebView));
mWebView.setDefaultHandler(new MyHandlerCallback());
mWebView.setWebChromeClient(new WebChromeClient());
//开启webView的LocalStorage功能,使H5可以保存数据
mWebView.getSettings().setDomStorageEnabled(true);
//加载本地JS文件,实际项目中加载H5页面的url
mWebView.loadUrl("file:///android_asset/javascript.html");
//注册获取信息方法,供JS调用
mWebView.registerHandler("getInfomation", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
String responseData = "";
Log.d("TestJsBridgeLog", "data from JS: " + data);
if(data.contentEquals("deviceStatus")) {
if(deviceStatus) {
responseData = "开";
} else {
responseData = "关";
}
} else if(data.contentEquals("deviceType")) {
responseData = deviceType;
}
//回调返回给JS
function.onCallBack(responseData);
}
});
//注册控制设备状态方法,供JS调用
mWebView.registerHandler("controlDevice", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
String responseData = "";
Log.d("TestJsBridgeLog", "data from JS: " + data);
if(data.contentEquals("open")) {
deviceStatus = true;
responseData = "打开设备成功";
} else if (data.contentEquals("close")){
deviceStatus = false;
responseData = "关闭设备成功";
} else {
responseData = "参数错误";
}
//回调返回给JS
function.onCallBack(responseData);
}
});
//调用send方法向JS发送消息
mWebView.send("Hello JS!");
//webView调用JS的方法发送数据
mWebView.callHandler("functionInJs", myData, new CallBackFunction() {
@Override
public void onCallBack(String responseData) {
//打印JS回复的消息
Log.d("TestJsBridgeLog", "responseData from JS: " + responseData);
}
});
}
class MyWebViewClient extends BridgeWebViewClient {
public MyWebViewClient(BridgeWebView webView) {
super(webView);
}
//每次页面加载完成时,获取H5页面的title,可以根据项目需要使用
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String title = view.getTitle();
if (!TextUtils.isEmpty(title)) {
log("onPageFinished title:" + title);
}
}
}
//接收JS通过send方法发送的消息
class MyHandlerCallback extends DefaultHandler {
@Override
public void handler(String data, CallBackFunction function) {
super.handler(data, function);
if (null != function) {
Log.d("TestJsBridgeLog", "data from JS: " + data);
function.onCallBack("收到JS消息");
}
}
}
//右滑时,返回上一个H5页面,H5页面多次跳转的项目中使用
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
效果图