使用iframe方式,以唤起Native;以唤起分享组件为例
// h5 js code 将它封装一下
function createIframe(url){
var url = ‘jsbridge://getShare?title=分享标题&desc=分享形貌&link=http%3A%2F%2Fwww.douyu.com&cbName=jsCallClientBack’;
var iframe = document.createElement(‘iframe’);
iframe.style.width = ‘1px’;
iframe.style.height = ‘1px’;
iframe.style.display = ‘none’;
iframe.src = https://segmentfault.com/a/url;
document.body.appendChild(iframe);
setTimeout(function() {
iframe.remove();
}, 100);
}
然后客户端通过拦截这个哀求,并且解析出相应的方法和参数:这里以ios为例:
// IOS swift code
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let url = request.URL
let scheme = url?.scheme
let method = url?.host
let query = url?.query
if url != nil && scheme == “jsbridge” {
switch method! {
case “getShare”:
self.getShare()
default:
print(“default”)
}
return false
} else {
return true
}
}
看不懂就略过,非重点。。。。。
这里我们在哀求参数中加上了cbName=jsCallClientBack,这个jsCallClientBack为JS调用客户端所定义的回调函数,在业务层jsBridge封装中,我们传入一个匿名函数作为回调,底层将这个函数绑定在window的jsbridge对象下并为其定义一个独一无二的key,这个key就是jsCallClientBack,客户端在处理惩罚完逻辑后,会通过上面已经介绍过的方法来回调window下的方法。
ps: 在将回调绑定在window下时,特别注意要使用bind保持函数内this的原有指向不变
IOS客户端调用H5方法
Native调用Javascript语言,是通过UIWebView组件的stringByEvaluatingJavaScriptFromString方法来实现的,该方法返回js脚本的实行结果。
// IOS swift code
webview.stringByEvaluatingJavaScriptFromString(“window.methodName()”)
从上面代码可以看出它其实就是实行了一个字符串化的js代码,调用了window下的一个对象,如果我们要让native来调用我们js写的方法,那这个方法就要在window下能访问到。但从全局思量,我们只要暴露一个对象如JSBridge给native调用就好了。
调用客户端原生方法的回调函数也将绑在window下供客户端成功反调用,现实上一次调用客户端方法最后产生的结果是双向互相调用。
H5调用Android客户端方法
在安卓webView中有三种调用native的方式:
通过schema方式,客户端使用shouldOverrideUrlLoading方法对url哀求协议举行解析。这种js的调用方式与ios的一样,使用iframe来调用native方法。通过在webview页面里直接注入原生js代码方式,使用addJavascriptInterface方法来实现。
// android JAVA code
class JSInterface {
@JavascriptInterface
public String getShare() {
//…
return “share”;
}
}
webView.addJavascriptInterface(new JSInterface(), “AndroidNativeApi”);
上面的代码就是在页面的window对象里注入了AndroidNativeApi对象。在js里可以直接调用原生方法。
使用prompt,console.log,alert方式,这三个方法对js里是属性原生的,在android webview这一层是可以重写这三个方法的。一样平常我们使用prompt,由于这个在js里使用的不多,用来和native通讯副作用比较少。
// android JAVA code
class WebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
// 重写window下的prompt,通过result返回结果
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
}
}
一样平常而言安卓客户端选用1、2方案中的一种举行通信,从前端层面来讲,保举客户端都使用schema协议的方式,便于前端jsBridge底层代码的维护与迭代。
Android客户端调用H5方法
在安卓APP中,客户端通过webview的loadUrl举行调用:
// android JAVA code
webView.loadUrl(“javascript:window.jsBridge.getShare()”);
H5端将方法绑定在window下的对象即可,无需与IOS作区分
H5调用RN客户端
我们知道RN的webView组件现实上就是对原生容器的二次封装,因此我们不需要直接通过schema协议来通信,只需要使用欣赏器postMessage、onMessage来传递消息即可,类似于iframe,而真正的通信过程RN已经帮我们做了。
// h5 js code
window.postMessage(data);
// rn js code
<WebView
ref=“webView”
source={require(‘…/html/index.html’)}
injectedJavaScript={‘window.androidConfig = {}’} // 通过这个props可以在webView初始化时注入属性方法
onMessage={e => {
let { data } = e.nativeEvent;
//…
}}
/>
RN客户端调用H5
postMessage是双向的,以是也可以在RN里发消息,H5里接消息来触发对应的回调
this.refs.webView.postMessage({
cbName: ‘xxx’,
param: {}
});
前端jsBridge的封装
在了解了js与客户端底层的通信原理后,我们可以将IOS、安卓统一封装成jsBridge提供给业务层开发调用。
class JsBridge {
static lastCallTime
constructor() {
if (UA.isReactNative()) {
document.addEventListener(‘message’, function(e) {
window.jsClientCallBacke.data.cbName;
});
}
}
// 通用callNtive方法
callClient(functionName, data, callback) {
// 避免一连调用
if (JsBridge.lastCallTime && (Date.now() - JsBridge.lastCallTime) < 100) {
setTimeout(() => {
this.callClient(functionName, data, callback);
}, 100);
return;
}
JsBridge.lastCallTime = Date.now();
data = data || {};
if (callback) {
const cbName = randomName();
Object.assign(data, { cbName });
window.jsClientCallBack[cbName] = callBack.bind(this);
}
if (UA.isIOS()) {
data.forEach((key, value) => {
try {
data[key] = JSON.stringify(value);
} catch(e) { }
});
var url = ‘jsbridge://’ + functionName + ‘?’ parseJSON(data);
var iframe = document.createElement(‘iframe’);
iframe.style.width = ‘1px’;
iframe.style.height = ‘1px’;
iframe.style.display = ‘none’;
iframe.src = url;
document.body.appendChild(iframe);
setTimeout(() => {
文末
好了,本日的分享就到这里,如果你对在面试中遇到的标题,大概刚结业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的将来还不够了解不知道给如何规划,可以来看看偕行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作履历完善自己的之后的面试计划及职业规划。
这里放上一部分我工作以来以及参与过的大大小小的面试网络总结出来的一套进阶学习的视频及面试专题资料包,主要照旧希望大家在如今大情况欠好的情况下面试可以或许顺遂一点,希望可以资助到大家
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
ld(iframe);
setTimeout(() => {
文末
好了,本日的分享就到这里,如果你对在面试中遇到的标题,大概刚结业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的将来还不够了解不知道给如何规划,可以来看看偕行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作履历完善自己的之后的面试计划及职业规划。
这里放上一部分我工作以来以及参与过的大大小小的面试网络总结出来的一套进阶学习的视频及面试专题资料包,主要照旧希望大家在如今大情况欠好的情况下面试可以或许顺遂一点,希望可以资助到大家
[外链图片转存中…(img-uDgwEKL8-1715361726323)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |