dsBridge介绍
dsBridge是一个三端易用的现代跨平台 Javascript bridge, 通过它,你可以在Javascript和原生之间同步或异步的调用彼此的函数。
最近在开发h5相关的需求,而且相关的h5页面会嵌入到app,h5页面有拍照、上传照片、上传文件等,拍照和上传照片可以使用UI组件提供的功能,但是上传文件这块需要用到原生的上传方法了。调研之后,我选择了dsBridge这个跨平台的Javascript bridge。
我们先看一下如何在项目中使用的:
npm i dsbridge
我目前用的dsbridge版本是3.1.4
首先先封装dsbridge相关的方法
scr/lib/dsbridge.js
代码如下:
import dsBridge from 'dsbridge'
export default {
// js调用原生(native)的方法入口
callHandler(name,data,callback){
dsBridge.call(name,data,callback)
},
// 原生(Native)调用的方法使用此方法注册
registerHandler(tag,callback){
dsBridge.register(tag,callback)
}
}
然后在main.js中进行全局注册
// 集成jsbridge
import Bridge from './lib/dsbridge.js'
app.config.globalProperties.$bridge = Bridge
在对应的组件中使用的话
<script setup>
import { getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance() // 获取
// 拍照、上传照片、上传文件
function uploadFile(item){
proxy.$bridge.callHandler(
'photo.selectFileAndUpload',
{
action:item.value,
url:`${import.meta.env.VITE_APP_BASE_URL}/api/outer/file/upload`,
fileType:item.fileType,
recordId:item.recordId
},
(res)=>{
if(res.status != 'error'){
dealFile(res)
...
}
})
}
</script>
这个就是在项目中使用的流程。
我们来看一下在dsBridge的内部原理
1、JavaScript
核心原理
- 封装DSBridge,
提供注册js的方法register: function (name, fun, asyn);
调用原生Native的方法call: function (method, args, cb) 等 - 使用全局对象window,往window注入全局参数,如存储js的注册方法等。
- native调用的js方法动态注入
提供bridge.register(name, fun)接口,使用key-value的方式将方法func和方法名method_name。
源码核心
- JS ----> Native核心:以下是源码缩减版本~
var bridge = {
// js调用native的方法入口
call: function (method, args, cb) {
arg = JSON.stringify(arg)
if(window._dsbridge){
ret= _dsbridge.call(method, arg)
}else if(window._dswk||navigator.userAgent.indexOf("_dsbridge")!=-1){
//使用时Native会注册_dswk参数
// 调用prompt函数,Native会拦截prompt事件,然后执行
ret = prompt("_dsbridge=" + method, arg);
}
return JSON.parse(ret||'{}').data
},
// 原生Native调用的方法使用此方法注册
register: function (name, fun, asyn) {
//注册的方法会保存到_dsaf或_dsf中
var q = asyn ? window._dsaf : window._dsf
//object类型保存到_obs下,方法直接保存到_dsf(_dsaf)下
if (typeof fun == "object") {
q._obs[name] = fun;
} else {
q[name] = fun
}
}
};
- Native---->JS核心:以下是源码缩减版本~
//立即执行函数
!function () {
//判断是否需要给window进行参数添加,如果没有添加会把ob内参数进行一次添加
if (window._dsf) return;
var ob = {
_dsf: {//存储同步方法
_obs: {}//存储同步方法相关object
},
_dsaf: {//存储异步方法
_obs: {}//存储异步方法相关object
},
dscb: 0,//避免方法同名每次加1
dsBridge: bridge,
_handleMessageFromNative: function (info) { //处理Native调用js方法,核心实现如下
// 通过info.method 获取方法实现
var f = this._dsf[info.method];
// 通过info.data 获取入参,数组形式
var arg = JSON.parse(info.data);
// 使用apply函数,调用函数
f.apply(ob, arg)
} //end
} // var ob end
}//func end