Hybrid app本地开发如何调用JSBridge

简介: Hybrid app本地开发如何调用JSBridge

1、背景


公司研发的一款服务软件App(姑且称为“大地”),提供了包涵消息、待办、工作台、同事圈和通讯录五大功能模块,其中,工作台里集成了包括公司的移动客户端、PC端以及第三方平台的部分功能/服务(统称为“应用”)。


我今天要讲的是这个集成平台以什么方式展现“应用”,答案是:借鉴了微信的架构,自研了“小程序”接入“应用”。


我司小程序具有一种相对开放能力(面向全公司),赋能业务快速数字化、场景敏捷迭代,并且可在“大地”上便捷的获取和使用,同时具有完善的使用体验(这就是严格的接入审核标准带来的好处)。


在“大地”开发者平台,创建小程序会自动创建配套的公众号(公众号是为了推送消息使用,可订阅)。小程序开发不限制技术选型,开发完成之后按照小程序接入规范打包上架小程序,审核发布。


简单来说,可以把“大地”看成是一个“钉钉”,我现在要把我们的业务功能投放到“大地”上,就需要接入“大地”小程序,以小程序的方式在“大地”上为用户提供服务。


小程序架构:Cordova框架做的WebView,运行我开发的前端程序,通过Nginx帮我把请求代理到微服务网关,由网关转发到目的主机处理请求。它虽然看上去是一个Native App,但只有一个UI WebView,里面访问的是一个Web App,对我来说就是开发一个H5应用调用一些所需的JSBridge,也就是所谓的Hybrid App

下面看一下本地开发中的一些问题,以及我是怎么处理的


2、问题


Hybrid App本地开发过程中没有真实的Native环境的,同样也无法使用JSBridge,这就会带来一个问题:跟原生交互的行为只能发布小程序才可以调试,本地玩不了,这...,相当fuck。


目的是想让本地开发同小程序测试环境具有相同的体验,我的想法是在本地模拟JSBridge的方法,尽管不能带来真实的效果,至少触发了某个行为之后要有个反应,不至于让操作流程看起来像是“脱节”的(实际跟原生的交互行为并不多,比如:拍照、弹窗提示、定位等等)。


因此,我要做的就是本地模拟JSBridge的一些方法,开发时触发了这些原生交互行为之后提示一些信息,等到上架小程序测试环境时,在手机上会用真实的JSBridge方法自动替换掉我模拟实现的方法。


于是我就开始了下面的准备工作。


  1. 搞清楚JSBridge运行的原理
  2. 本地模拟JSBridge的方法
  3. 上架小程序是自动使用真实的JSBridge


3、了解JSBridge


JSBridge:望文生义就是jsNative之前的桥梁,而实际上JSBridge确实是JSNative之前的一种通信方式。


简单的说,JSBridge就是定义NativeJS的通信,Native只通过一个固定的桥对象调用JSJS也只通过固定的桥对象调用NativeJSBridge另一个叫法及大家熟知的Hybrid app技术。

image.png

了解即可,更多的请参考


下图展示了JSBridge工作流程👇

image.png

上图中左侧部分正式我要做的,具体请看下文

看累了,三连一下,回看不迷路哟😉


3.1、我们的JSBridge


推测“大地”那边的JSBridge应该是自己写的,没有初始化JSBridge的操作

当调用JSBridge时,必须在页面完全加载完成之后才能够拿到全局的JSBridgeCordova框架提供deviceready事件,该事件触发的时候表示全局的JSBridge挂载成功。(注意:这就是我接下来操作的切入点,嘻嘻)


简单写下如下:

document.addEventListener('deviceready', function () {
  console.log('deviceready OK!');
  JSAPI.showToast(0, '提示信息')
}, false)

需要注意的是,在开发环境,是没有 deviceready 事件的,所以上面的代码并不会执行,只有在app里面运行的时候才会执行。


思考:


JSBridge必须是在deviceready事件触发后方能使用的,因此首先要做的就是自定义deviceready事件,本地环境可以在load事件里触发自定义deviceready事件,生产环境下监听deviceready事件即可

image.png


4、JS发起自定义事件


我是用 CustomEvent 构造函数,继承至 Event,文档看这里


  1. 用法
new CustomEvent(eventName, params);


  1. 示例


创建一个自定义事件

const event=new CustomEvent('mock-event'); 


  1. 传递参数


这里值得注意,需要把想要传递的参数包裹在一个包含detail属性的对象,否则传递的参数不会被挂载

function createEvent(params, eventName = 'mock-event') {
    return new CustomEvent(eventName, { detail: params });
}
const event = createEvent({ id: '0010' });


  1. 发起事件


调用dispatchEvent方法发起事件,传入你刚才创建的方法

window.dispatchEvent(event); 
  1. 监听事件
window.addEventListener('mock-event', ({ detail: { id } }) => {
    console.log('id',id) // 会在控制台打印0010
});
  1. 示例:
document.body.addEventListener('show', (event) => { console.log(event.detail); });
// 触发
let myEvent = new CustomEvent('show', {
    detail: {
        username: 'xixi',
        userid: '2022'
    }
});
document.body.dispatchEvent(myEvent);

了解了自定义事件之后,通过自定义事件模拟触发deviceready事件,这样上面的 deviceready 事件监听就可以执行了。

注意:这里还要确定一个问题,在什么时候触发自定义事件deviceready呢?


5、确定 deviceready 事件执行时机


  • 只需要编写如下代码,查看输出结果即可
window.addEventListener('load', function () {
  console.log('load OK!');
}, false);
document.addEventListener('deviceready', function () {
  console.log('deviceready OK!');
}, false);
  • 结果输出
load OK!
deviceready OK!

由此可知,执行顺序:load --> deviceready


6、自定义事件模拟Cordovadeviceready事件


  1. 自定义deviceready事件
  2. 根据上面测试执行顺序得出的结论,我在load事件里触发自定义事件
  3. 在开发环境下模拟一些用到的JSBridge-API,比如下面写到的 JSAPI.showToast() 方法
  • mockEvent.js
if (process.env.NODE_ENV === 'development') {
  //  自定义事件
  let myEvent = new CustomEvent('deviceready');
  // 模拟JSAPI事件
  window['JSAPI'] = {
    showToast(type, desc) {
      console.log(type, desc);
    }
  }
  // ...
  // 开发环境下,在 原生 load 方法之后 触发自定义事件
  window.addEventListener('load', function () {
    console.log('load OK!');
    setTimeout(() => {
      document.body.dispatchEvent(myEvent);
    }, 100)
  }, false);
}


7、封装deviceReady方法


实现在Cordova框架触发deviceready事件的时候感知到,以便于在deviceReady事件触发后执行JS-API


可用于开发环境和非开发环境


7.1、方式一


这里采用链式调用的方式,

以下这种借助 Promise 的实现,在这种场景下其实是不合理的👀 只是形式上类似,其实并不是


  1. 定义
  • mixin.js
deviceReady() {
  return new Promise((resolve) => {
    window.addEventListener('deviceready', function () {
      resolve("ready go!");
    }, false);
  })
}
  1. 组件内使用JS-API

使用JSAPI可以如下这么写

this.deviceReady().then((res) => {
  console.log(res); // ready go!
  JSAPI.showToast(0, '提示')
})
this.deviceReady().then((res) => {
  JSAPI.getUserInfo((res) => {
    console.log(res);
  }, (err) => {
    console.log(err);
  });
})
  1. 开发环境执行效果如下

image.png


7.2、方式二(推荐)


改写成通用的事件监听函数,支持链式调用

  • 开发环境下,由mockEvent.js文件里的dispatchEvent触发自定义的deviceready事件;
  • 小程序里运行,则由真实的deviceready事件触发
  1. 定义
  • mixin.js
receiver(type) {
  let callbacks = {
      fns: [],
      then: function(cb){
          this.fns.push(cb);
          return this;
      }
  };
  document.addEventListener(type, function(ev) {
    let fns = callbacks.fns.slice();
    for(let i = 0, l = fns.length; i < l; i++){
        fns[i].call(this, ev);
    }
  });
  return callbacks;
}
  1. 使用
this.receiver('deviceready').then((ev) => { 
  console.log(ev);
  JSAPI.getUserInfo(
    (res) => {
      console.log(res);
    },
    (err) => {
      console.log(err);
    }
  )
})
this.receiver("click")
  .then(() => console.log("hi"))
  .then(()=> console.log(22));


最后


当应用发布到app上,就是监听的真实的 Cordova框架的 deviceready 事件了,之后也就可以拿到真实的JSAPI了,以上只是为了在开发环境的时候模拟使用JSAPI。防止在开发环境下直接调用JSAPI飘红的情况,当然也是可以加try catch处理的,只不过个人感觉模拟事件使得代码看起来更加优雅别致一点,使用更加丝滑,酌情食用😁。

软件架构非常有意思,感兴趣的可以交流探索,嘻嘻。

目录
相关文章
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
8天前
|
安全 JavaScript 前端开发
小游戏源码开发之可跨app软件对接是如何设计和开发的
小游戏开发团队常需应对跨平台需求,为此设计了成熟的解决方案。流程涵盖游戏设计、技术选型、接口设计等。首先明确游戏功能与特性,选择合适的技术架构和引擎(如Unity或Cocos2d-x)。接着设计通用接口,确保与不同App的无缝对接,并制定接口规范。开发过程中实现游戏逻辑和界面,完成登录、分享及数据对接功能。最后进行测试优化,确保兼容性和性能,发布后持续维护更新。
|
10天前
|
前端开发 Java 测试技术
语音app系统软件源码开发搭建新手启蒙篇
在移动互联网时代,语音App已成为生活和工作的重要工具。本文为新手开发者提供语音App系统软件源码开发的启蒙指南,涵盖需求分析、技术选型、界面设计、编码实现、测试部署等关键环节。通过明确需求、选择合适的技术框架、优化用户体验、严格测试及持续维护更新,帮助开发者掌握开发流程,快速搭建功能完善的语音App。
|
11天前
|
机器学习/深度学习 存储 人工智能
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
884 14
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
|
11天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
141 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
12天前
|
供应链 数据挖掘 API
1688APP 原数据 API 接口的开发、应用与收益
1688作为阿里巴巴旗下的B2B平台,汇聚海量供应商和商品资源。其APP原数据API接口为开发者提供获取商品详细信息的强大工具,涵盖商品标题、价格、图片等。通过注册开放平台账号、申请API权限并调用接口,开发者可构建比价工具、供应链管理及自动化上架工具等应用,提升用户体验与运营效率,创造新的商业模式。示例代码展示了如何使用Python调用API并解析返回结果。
68 8
|
14天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
37 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
16天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
121 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
24天前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
75 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
26天前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
27 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

热门文章

最新文章

  • 1
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
  • 4
    【Azure App Service】基于Linux创建的App Service是否可以主动升级内置的Nginx版本呢?
  • 5
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 6
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 7
    【Azure Function】Function App出现System.IO.FileNotFoundException异常
  • 8
    【Azure Logic App】使用MySQL 新增行触发器遇见错误 :“Unknown column 'created_at' in 'order clause'”
  • 9
    阿里云APP备案流程图以及备案所需材料整理,跟着教程一步步操作
  • 10
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程