概述
在混合模式移动应用开发中,为了实现h5自身不具备的功能,不可避免的会产生h5与原生的交互。但是h5跟原生是不相通,他们之间的联系是通过一座桥来进行联系,这就是jsBridge。
至于jsBridge的实现原理,网上各种介绍的文章比比皆是,这里不再赘述,这也不是本文的重点。本文的重点是介绍jsBridge 在开发中的解决方案,怎样用最舒服的姿势来使用jsBridge。
插件
@zebing/js-bridge 插件是适配多平台的jsBridge交互插件,目前已经在android,ios以及windows qt开发的应用中使用,效果显著。极大的解决了各平台之间的差异,以及本地开发原生接口不可调试的问题。
使用
1. 默认交互方案
插件默认提供了无感使用的方案,只针对android和ios,只要h5跟native端遵循以下规则。
native端:
// android
// 将方法注入到 window.jsBridgeMethods 中
// ios
// 通过 messageHandlers 进行交互
android和ios两端方法接收到的参数是一个json字符串,格式如下:
{
xxx: "参数1",
xxx: "参数2",
...
callback?: "回调函数名称", // 通过window[callbackName] 进行回调
}
h5端:
import jsBridge from '@zebing/js-bridge';
// test 为调用的方法名
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})
2. 自定义适配器交互方案
如果默认交互方案不满足,可以自定义适配器进行交互。通过调用create 进行初始化。以安卓端为例,如下:
import { create, register } from '@zebing/js-bridge'
const JsBridge = create([{
platform () {
if (typeof window !== 'object') {
return false;
}
const userAgent = window.navigator.userAgent;
return userAgent.indexOf('Android') > -1 || userAgent.indexOf('Adr') > -1;
},
support (name) {
const apis = window['jsBridgeMethods'] || {};
const support = Object.prototype.toString.call(apis[name]) === '[object Function]';
return support;
},
run (name, options) {
window.jsBridgeMethods[name](JSON.stringify(options));
}
}]);
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})
create 接收一个数组,可传入多个适配器。一个平台只会使用一个符合条件的适配器。即使传入的适配器有多个符合,后面的会忽略。
适配器必须满足以下条件:
- platform 方法,用以判断是否适用当前平台。
- support 方法, 用以判断要调用的方法是否可调用。
- run 方法,用以执行调用原生方法进行交互。
用户与原生交互不能使用 platform, support, run 三个方法名
3. 本地开发调试
本地开发调试这也是本插件的一大特色。具体如下: 在根目录下新建文件js-bridge.methods.js文件
// js-bridge.methods.js 文件内容
module.exports = {
test (options) {
const { id, callback } = JSON.parse(options);
window[callback]({ id, result: 'test ok' });
},
}
然后新建js-bridge.js文件通过create创建实例
import { create } from '@zebing/js-bridge';
const adapter = [];
// 本地开发模拟原生交互
if (process.env.BUILD_ENV === 'development') {
const bridgeMethods = require(`../../bridge.methods.js`);
if (process.client) {
window.jsBridgeMethods = bridgeMethods;
adapter.push({
platform: () => true,
support: (name) => typeof (window.jsBridgeMethods || {})[name] === 'function',
run (name, options) {
window.jsBridgeMethods[name](JSON.stringify(options));
}
})
}
}
// 安卓jsBridge适配器,ios使用默认适配器
adapter.push({
platform () {
if (typeof window !== 'object') {
return false;
}
const userAgent = window.navigator.userAgent;
return userAgent.indexOf('Android') > -1 || userAgent.indexOf('Adr') > -1;
},
support: (name) => typeof (window.jsBridgeMethods || {})[name] === 'function',
run (name, options) {
window.jsBridgeMethods[name](JSON.stringify(options));
}
})
export default create(adapter);
最后引入jsBridge进行调用
import jsBridge from 'js-bridge.js'
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})
4. 使用Promise代替callback
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})
可改为
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: true,
}).then((result) => {
})
5. 兼容安卓4.4 及以下低端机
由于 jsBridge.test 调用方式采用了Proxy代理,因此会存在安卓4.4 及以下低端机不兼容的问题。但是提供了兼容的方案。如下:
// 将调用方式
jsBridge.test({
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})
替换成
jsBridge.run('test', {
xxx: '参数1',
xxx: '参数2',
callback: function () {}
})