文中的代码是在Android与JS交互篇–JSBridge的使用 - CSDN博客 的基础上做了一丝丝的改动。
学习资料:
1.Hybrid APP混合开发理论知识讲解 - CSDN博客 https://blog.csdn.net/hope_for_android/article/details/77564509
2.Hybrid APP基础篇(四)->JSBridge的原理 - 撒网要见鱼 - 博客园 http://www.cnblogs.com/dailc/p/5931324.html
3.JsBridge第三方框架GitHub地址—— lzyzsd/JsBridge: android java and javascript bridge, inspired by wechat webview jsbridge https://github.com/lzyzsd/JsBridge
4.具体项目——Android与JS交互篇–JSBridge的使用 - CSDN博客 https://blog.csdn.net/chx_w/article/details/79473980
H5直接调用native的send方法,native在(自定义Handler回调)MyHandlerCallBack的Handler里接收,并可通过onCallBack方法回传数据给web。
整个流程:在H5中,点击按钮则给native发送数据,并接收native反馈回的信息。
H5中:
H5按钮:
type="button" id="send" value="发消息给Native" οnclick="sendClick();" />
H5按钮的sendClick():
function sendClick() {
var name = document.getElementById("uname").value;
var pwd = document.getElementById("psw").value;
var data = "name = " + name + ", password = " + pwd;
window.WebViewJavascriptBridge.send(
data,
function(responseData) {
//responseData为native回馈给h5的信息
document.getElementById("show").innerHTML = responseData
}
);
}
native中:
//Handler做为通信桥梁的作用,接收处理来自H5数据及回传Native数据的处理,当h5调用send()发送消息的时候,调用MyHandlerCallBack
bridgeWebview.setDefaultHandler(new MyHandlerCallBack(mOnSendDataListener));
mOnSendDataListener:
private MyHandlerCallBack.OnSendDataListener mOnSendDataListener;
mOnSendDataListener = new MyHandlerCallBack.OnSendDataListener() {
@Override
public void sendData(String data) {
editText.setText("通过webview发消息接收到数据:\n" + data);
}
};
自定义Handler回调(MyHandlerCallBack):
import android.text.TextUtils;
import android.util.Log;
import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
/**
* 自定义Handler回调
*/
class MyHandlerCallBack implements BridgeHandler {
private static String TAG = "MyHandlerCallBack";
private OnSendDataListener mSendDataListener;
public MyHandlerCallBack(OnSendDataListener mSendDataListener){
this.mSendDataListener = mSendDataListener;
}
@Override
public void handler(String data, CallBackFunction function) {
Log.d(TAG,"接收数据为:" + data);
if (!TextUtils.isEmpty(data) && mSendDataListener != null) {
mSendDataListener.sendData(data);
}
function.onCallBack("Native已收到消息!");
}
public interface OnSendDataListener {
void sendData(String data);
}
}
h5通过和Native统一命名方法名,如h5通过方法名submitFromWeb来调取java代码,native中则需注册此方法。有方法名的都需要注册Handler后才能使用,在native中写法如下mBridgeWebview.registerHandler("submitFromWeb", new BridgeHandler() {...});
此处以方法“submitFromWeb”为例!
整个流程:在H5中,点击按钮则给native发送数据,并接收native反馈回的信息。
H5中:
H5按钮:
type="button" id="use" value="调用Native方法" οnclick="useClick();" />
H5按钮的useClick()方法:
function useClick() {
var name = document.getElementById("uname").value;
var pwd = document.getElementById("psw").value;
var data = "name = " + name + ", password = " + pwd;
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb', {
'info': data
},
function(responseData) {
document.getElementById("show").innerHTML = responseData;
}
);
}
native中:
bridgeWebview.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
//data为H5传递给native的数据
if (!TextUtils.isEmpty(data)) {
editText.setText("web通过调用Native方法接收到web传递过来的数据:\n" + data);
}
//native反馈信息给web
function.onCallBack("Native已经接收到数据:" + data + ",请web确认!");
}
});
注意:在H5和native中,方法名必须一致!
初始化bridge成功后反馈数据给native,native传递初始化数据给web。
H5中:
function connectWebViewJavascriptBridge(callback) {
if(window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
connectWebViewJavascriptBridge(function(bridge) {
//也注册默认的Handler,用来接收java调用的send(string,CallBackFunction)方法
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': '测试中文!'
};
console.log('JS responding with', data);
//初始化bridage反馈给native信息,native在bridgeWebview.send("str", new CallBackFunction() {...});中接收反馈信息
responseCallback(data);
});
//注册handler等待java代码调用
//初始化时获取数据是调用此处代码
//参数:标识,要传递到JAVA的数据,回调方法。
//JAVA代码响应的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
bridge.registerHandler("functionInJs", function(data, responseCallback) {
//data为native传递给web的数据
var json = data;
//web反馈信息给native
//native在bridgeWebview.callHandler("functionInJs", new Gson().toJson(zoneList), new CallBackFunction() {...});中接收反馈信息
var responseData = "I am javascript, Data reception success!";
responseCallback(responseData);
});
})
native中:
//应用启动后,native发数据给web显示
//应用启动后初始化数据调用,js处理方法connectWebViewJavascriptBridge(function(bridge)
//H5在bridge.registerHandler()中接收native传递的数据new Gson().toJson(zoneList)
bridgeWebview.callHandler("functionInJs", new Gson().toJson(zoneList), new CallBackFunction() {
@Override
public void onCallBack(String data) {
//data为web反馈回来的数据
editText.setText("向h5发送初始化数据成功,接收h5返回值为:\n" + data);
}
});
//bridge.init:对应js中的bridge.init处理,此处需加CallBackFunction,如果只使用mBridgeWebview.send("");会导致js中只收到通知,接收不到值
//接收来自H5中bridge.init的反馈数据
bridgeWebview.send("来自java的发送消息!!!", new CallBackFunction() {
@Override
public void onCallBack(String data) {
//data:web初始化bridge成功后反馈回来的数据
Toast.makeText(MainActivity.this, "bridge.init初始化数据成功" + data, Toast.LENGTH_SHORT).show();
}
});
此处以方法名“nativeFunction”为例!
native中:
String data = new Gson().toJson(zoneList);
//直接调用H5中的nativeFunction方法向H5发送数据
bridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");
H5中:
function nativeFunction(data) {
//data为native传递给web的数据
var json = data;
}
注意:Native和H5中的方法名必须一致。
repositories {
maven { url "https://jitpack.io" }//jsbridge
}
compile 'com.github.lzyzsd:jsbridge:1.0.4'//jsbridge
compile 'com.google.code.gson:gson:2.2.4'//gson是为了把对象转换成Json字符串使用的
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/bridge_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp" />
设置属性:
private static String URL_HTML = "file:///android_asset/"+"post.html";//加载网页地址:assets文件路径(固定代码格式:"file:///android_asset/"+"xxx.html")
//辅助WebView设置处理关于页面跳转,页面请求等操作
bridgeWebview.setWebViewClient(new MyWebViewClient(bridgeWebview, MainActivity.this));
//Handler做为通信桥梁的作用,接收处理来自H5数据及回传Native数据的处理,当h5调用send()发送消息的时候,调用MyHandlerCallBack
bridgeWebview.setDefaultHandler(new MyHandlerCallBack(mOnSendDataListener));
//WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比等,不过它还能处理文件上传操作
//bridgeWebview.setWebChromeClient(new MyChromeWebClient());//自定义 WebChromeClient 辅助WebView处理图片上传操作
// 如果不加这一行,当点击界面链接,跳转到外部时,会出现net::ERR_CACHE_MISS错误
if (Build.VERSION.SDK_INT >= 19) {
bridgeWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
//加载网页地址(支持本地和远程)
bridgeWebview.loadUrl(URL_HTML);
bridge的初始化数据和回调:
//*******************bridge的初始化数据和回调*********************************
//应用启动后,native发数据给web显示
//应用启动后初始化数据调用,js处理方法connectWebViewJavascriptBridge(function(bridge)
//H5在bridge.registerHandler()中接收native传递的数据new Gson().toJson(zoneList)
bridgeWebview.callHandler("functionInJs", new Gson().toJson(zoneList), new CallBackFunction() {
@Override
public void onCallBack(String data) {
//data为web反馈回来的数据
editText.setText("向h5发送初始化数据成功,接收h5返回值为:\n" + data);
}
});
//bridge.init:对应js中的bridge.init处理,此处需加CallBackFunction,如果只使用mBridgeWebview.send("");会导致js中只收到通知,接收不到值
//接收来自H5中bridge.init的反馈数据
bridgeWebview.send("来自java的发送消息!!!", new CallBackFunction() {
@Override
public void onCallBack(String data) {
//data:web初始化bridge成功后反馈回来的数据
Toast.makeText(MainActivity.this, "bridge.init初始化数据成功" + data, Toast.LENGTH_SHORT).show();
}
});
处理返回键,在webview界面,按下返回键,不退出程序:
/**
* 处理返回键,在webview界面,按下返回键,不退出程序
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 处理返回键,在webview界面,按下返回键,不退出程序
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (bridgeWebview != null && bridgeWebview.canGoBack()) {
bridgeWebview.goBack();
return true;
}else {
System.exit(0);
}
}
return super.onKeyDown(keyCode, event);
}
1.在libs文件夹中添加jquery-3.3.1.js
,下载地址Download jQuery | jQuery 、jquery下载所有版本(实时更新) 。。。。。。为项目引进jquery框架。
2.新建html的文件夹,结构图如下:
最外层文件夹名assets
不能错,这个是固定格式!里面的文件夹名不强求。
WebViewJavascriptBridge.js文件里写了H5注册初始化JSBridge相关的种种方法!!!