H5与native交互之JSBridge
JSBridge
1. Why do we need JSBridge?
2. Why is “JS”Bridge?
3. What is JSBridge?
Why do we need JSBridge?
背景
随着HTML5的不断普及及优化,其在移动端开发的应⽤也越来越多。
why?
H5是跨平台的
依托浏览器运⾏,不⽤区分ios或者安卓去做不同的版本的开发,这样可以节约开发成本。当然在ios和安卓各种机型下是需要去适配的,⽐如⼤家⽐较熟悉的rem布局以及flex布局等等。
客户端发版限制
尤其是ios,要审核。⽐如要急着上线⼀个功能或者活动,那么这时就需要h5。还有就是⼀些可能会频繁改动或者新增的功能,⽐如商品详情这种,新增品类啊,某种品类新增类⽬啊等等,更新频繁的,如果⽤native开发的话,要频繁的发版,这就不⼤现实。这也是为什么现在⼤家⽐较推崇的Hybird混合开发。
顾名思义,JSBridge是⼀座⽤JavaScript搭建起来的桥,⼀端是H5,⼀端是native。我们搭建这座桥的⽬的也很简单,让native可以调⽤H5的“调⽤”原⽣的代码。
js代码,让H5可以“调⽤”
Why is “JS”Bridge
为什么是JSbridge ?,⽽不是iOS/安卓 bridge,那是因为这个桥,是通过js来搭建的,也就是⽤js来写的。
这个⽐较容易理解,web端⽀持JavaScript,native有webview,webview可以在所加载的页⾯加载完成后调⽤页⾯的JavaScript代码。所以,使⽤JavaScript就理所当然了。
What is JSBridge?
1.Android
2. IOS
js获取json的key和valueAndroid调⽤JS
WebView.loadUrl(“javascript:function()”)
mWebView.loadUrl("Finish(port,jsonObj);");
JS调⽤Android
WebView的JavascriptInterface
WebViewClient.shouldOverrideUrlLoading()
WebView的Ja va sc r iptInterfa c e
是Android官⽅提供的⼯js和Native通信⽅案
1,实现⼀个java类
public class JavascriptInterface {
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
}
2,在webView中注册这个类
webView.addJavascriptInterface(new JavascriptInterface(), "javascriptInterface");
3,在js中直接调⽤这个接⼝
function showToast(text){
window.javascriptInterface.showToast(text);
}
WebView Client.sho uldOverrideU rlLo a ding()
这个⽅法是拦截所有webView的跳转,页⾯可以构造⼀个特殊格式的Url跳转,shouldOverrideUrlLoading拦截Url后判断其格式,然后Native 就能执⾏⾃⾝的逻辑了
⽐如⽤ iframe 打开⼀个schema协议
public class CustomWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isJsBridgeUrl(url)) {
// JSbridge的处理逻辑
return true;
}
return super.shouldOverrideUrlLoading(view, url);
WebChro meClient.o nCo nso leMessa ge()
WebChr o m eClient.o
在js中执⾏console.log(), 会进⼊Android的soleMessage()回调
public class CustomWebChromeClient extends WebChromeClient {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
String msg = ssage();//Javascript输⼊的Log内容
}
WebChro meClient.o nJsPro mpt()
WebChr o m eClient.o m pt()
在js中执⾏alert、confirm和prompt这三个⽅法时,会进⼊Android的onJsAlert、onJsConfirm和onJsPrompt回调
由于prompt的使⽤频率较低,因此通常采⽤prompt实现js和Native的通信
1. 设计schema
和⽹站的http协议⼀样,约定⼀个js和Android的通信协议
var JSBridgeUrl = 'JSBridge://className:callbackAddress/methodName?jsonObj';
// className: 表⽰java的类名
// callbackAddress: js回调的标识
// methodName: java中的⽅法名
// jsonObj: 接⼝数据
2,在js中,可以采⽤如下⽅法调⽤安卓的⽅法
var JSBridge = {
call: function(className, method, params, callback){
var uri = 'JSBridge://' + className + ':' + callback + '/' + method + '?' + params;
window.prompt(uri, "");
}
}
// 下⾯会调⽤java中的 bridge.showToast⽅法
JSBridge.call('bridge','showToast',{'msg':'Hello JSBridge'},
function(res){alert(JSON.stringify(res))});
3,在java中, 可以如下实现:
public class JSBridgeWebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { firm(JSBridge.callJava(view, message));
return true;
}
// 调⽤java逻辑
public class JSBridge {
...
public static String callJava(WebView webView, String uriString) {
String methodName = "";
String className = "";
String param = "{}";
String port = "";
if (!TextUtils.isEmpty(uriString) && uriString.startsWith("JSBridge")) {
Uri uri = Uri.parse(uriString);
className = Host();
param = Query();
port = Port() + "";
String path = Path();
if (!TextUtils.isEmpty(path)) {
methodName = place("/", "");
}
}
// 基于上⾯的className、methodName和port path调⽤对应类的⽅法if (ainsKey(className)) { HashMapmethodHashMap = (className);
if (methodHashMap != null && methodHashMap.size() != 0 && ainsKey(methodName)) {
Method method = (methodName);
if (method != null) {
try {
method.invoke(null, webView, new JSONObject(param), new Callback(webView, port));
} catch (Exception e) {
e.printStackTrace();
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论