jsBridge跨平台统一解决方案,业务与技术分离,提升开发效率

1,856 阅读3分钟

概述

在混合模式移动应用开发中,为了实现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 接收一个数组,可传入多个适配器。一个平台只会使用一个符合条件的适配器。即使传入的适配器有多个符合,后面的会忽略。

适配器必须满足以下条件:

  1. platform 方法,用以判断是否适用当前平台。
  2. support 方法, 用以判断要调用的方法是否可调用。
  3. 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 () {}
})