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
方法自动替换掉我模拟实现的方法。
于是我就开始了下面的准备工作。
搞清楚
JSBridge
运行的原理本地模拟
JSBridge
的方法上架小程序是自动使用真实的
JSBridge
3、了解JSBridge
JSBridge:望文生义就是js
和Native
之前的桥梁,而实际上JSBridge
确实是JS
和Native
之前的一种通信方式。
简单的说,JSBridge
就是定义Native
和JS
的通信,Native
只通过一个固定的桥对象调用JS
,JS
也只通过固定的桥对象调用Native
。JSBridge
另一个叫法及大家熟知的Hybrid app
技术。
了解即可,更多的请参考
下图展示了JSBridge
的工作流程
上图中左侧部分正式我要做的,具体请看下文
看累了,三连一下,回看不迷路哟
3.1、我们的JSBridge
推测“大地”那边的JSBridge
应该是自己写的,没有初始化JSBridge
的操作
当调用JSBridge
时,必须在页面完全加载完成之后才能够拿到全局的JSBridge
,Cordova
框架提供deviceready
事件,该事件触发的时候表示全局的JSBridge
挂载成功。(注意:这就是我接下来操作的切入点,嘻嘻)
简单写下如下:
document.addEventListener('deviceready', function () {
console.log('deviceready OK!');
JSAPI.showToast(0, '提示信息')
}, false)
需要注意的是,在开发环境,是没有 deviceready
事件的,所以上面的代码并不会执行,只有在app
里面运行的时候才会执行。
思考:
JSBridge
必须是在deviceready
事件触发后方能使用的,因此首先要做的就是自定义deviceready
事件,本地环境可以在load
事件里触发自定义deviceready
事件,生产环境下监听deviceready
事件即可
4、JS发起自定义事件
我是用 CustomEvent
构造函数,继承至 Event
,文档看这里
- 用法
new CustomEvent(eventName, params);
- 示例
创建一个自定义事件
const event=new CustomEvent('mock-event');
- 传递参数
这里值得注意,需要把想要传递的参数包裹在一个包含detail
属性的对象,否则传递的参数不会被挂载
function createEvent(params, eventName = 'mock-event') {
return new CustomEvent(eventName, { detail: params });
}
const event = createEvent({ id: '0010' });
- 发起事件
调用dispatchEvent
方法发起事件,传入你刚才创建的方法
window.dispatchEvent(event);
- 监听事件
window.addEventListener('mock-event', ({ detail: { id } }) => {
console.log('id',id) // 会在控制台打印0010
});
- 示例:
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、自定义事件模拟Cordova
deviceready
事件
自定义
deviceready
事件根据上面测试执行顺序得出的结论,我在
load
事件里触发自定义事件在开发环境下模拟一些用到的
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
的实现,在这种场景下其实是不合理的
只是形式上类似,其实并不是
- 定义
- mixin.js
deviceReady() {
return new Promise((resolve) => {
window.addEventListener('deviceready', function () {
resolve("ready go!");
}, false);
})
}
- 组件内使用
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);
});
})
- 开发环境执行效果如下
7.2、方式二(推荐)
改写成通用的事件监听函数,支持链式调用
开发环境下,由
mockEvent.js
文件里的dispatchEvent
触发自定义的deviceready
事件;小程序里运行,则由真实的
deviceready
事件触发
- 定义
- 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;
}
- 使用
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
处理的,只不过个人感觉模拟事件使得代码看起来更加优雅别致一点,使用更加丝滑,酌情食用。
软件架构非常有意思,感兴趣的可以交流探索,嘻嘻。
我是 甜点cc
热爱前端,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚,等待着一个创业机会。主要致力于分享实用技术干货,希望可以给一小部分人一些微小帮助。
我排斥“新人迷茫,老人看戏”的现象,希望能和大家一起努力破局。营造一个良好的技术氛围,为了个人、为了我国的数字化转型、互联网物联网技术、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。
Hybrid app本地开发如何调用JSBridge的更多相关文章
- Hybrid APP混合开发的一些经验和总结
http://www.cnblogs.com/kingplus/p/5588339.html 写在前面: 由于业务需要,接触到一个Hybrid APP混合开发的项目.当时是第一次接触混合开发,有一些经 ...
- Hybrid APP混合开发
写在前面: 由于业务需要,接触到一个Hybrid APP混合开发的项目.当时是第一次接触混合开发,有一些经验和总结,欢迎各位一起交流学习~ 1.混合开发概述 Hybrid App主要以JS+Nativ ...
- Hybrid App 应用开发中 9 个必备知识点复习(WebView / 调试 等)
前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...
- Hybrid App混合模式开发的了解
Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具"Native App良好用户交互体验的优势"和"Web Ap ...
- (一)Hybrid app混合开发模式
hybrid app是什么? 这里我们先看一下词条上的定义 Hybrid App:Hybrid App is a mobile application that is coded in both br ...
- SharePoint 2013 搭建app本地开发环境
使用SharePoint App,如果要通过应用程序目录分发 SharePoint 相关应用程序,如具有完全控制权限的 SharePoint 相关应用程序(无法部署到 Office 365 网站),则 ...
- 【Hybrid App】Hybrid App开发实战
[引言]近年来随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员, 技术成熟度,时间,项目需求等一堆的因素.因此,开发App的方案已经变得越来越 ...
- 跨平台 webapp 开发技术之 Hybrid App
前所知的 APP 开发模式有三种: 基于操作系统运行的 APP -> Native App,侧重于原生开发,用户体验好,需要安装才会升级 基于浏览器运行的 APP -> Web App,侧 ...
- Hybrid App开发实战
Hybrid App开发实战 作者 李秉骏 发布于 九月 04, 2013 | [引言]近年来随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员 ...
随机推荐
- WPF开发随笔收录-ScrollViewer滑块太小解决方案
一.前言 在WPF开发过程中,ScrollViewer是一个很常使用到的控件,在自己工作的项目中,收到一个反馈就是当ScrollViewer里面的内容太长时,滚动条的滑块就会变得很小,然后导致点击起来 ...
- Python教程——常用的os操作详情
Python自动的os库是和操作系统交互的库,常用的操作包括文件/目录操作,路径操作,环境变量操作和执行系统命令等. 文件/目录操作 获取当前目录(pwd): os.getcwd() 切换目录(cd) ...
- Java 集合常见知识点&面试题总结(上),2022 最新版!
你好,我是 Guide.秋招即将到来(提前批已经开始),我对 JavaGuide 的内容进行了重构完善,公众号同步一下最新更新,希望能够帮助你. 你也可以在网站(javaguide.cn)上在线阅读, ...
- CentOS6安装使用ntp同步时间
[root@server yum.repos.d]# yum install ntp已加载插件:fastestmirror, priorities, refresh-packagekit, secur ...
- 从Python到水一篇AI论文(核心 or Sci三区+)
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...
- 4-12 Spring Security + JWT
Spring Security + JWT 此前,在处理登录的业务中,当视为登录成功时,返回的字符串并不是JWT数据,则应该将此数据改为必要的JWT数据. @Service public class ...
- Keyboading 思路
0x01 前置芝士 还是先放个 link 吧. 所需知识点:BFS. 思维难度较高,实现简单. 0x02 题目大意:其实就是给你个图,按顺序走到相应的点,求所需最少步数(走到需要去的点会耗费一次步数) ...
- .Net CLR GC 动态加载短暂堆阈值的计算及阈值超量的计算
前言: 很多书籍或者很多文章,对于CLR或者GC这块只限于长篇大论的理论性概念,对于里面的如何运作模式,却几乎一无所知.高达近百万行的CPP文件,毕竟读懂的没有几个.以下取自CLR.Net 6 Pre ...
- 臭名远扬之 goto 语句
C 语言自学之 goto 语句 Dome1:以下程序实现从控制台输出1-10,使用goto语句,实现当输出完3之后跳出循环体. 1 #include <stdio.h> 2 3 int m ...
- mui 登录跳转到首页之后顶部选项卡不灵敏问题
前段时间开发一个用mui开发app的时候遇到了登录跳转到首页之后顶部选项卡会失灵的问题,多次尝试之后终于解决了,趁现在还有点印象记录一下吧. 一开始我是用mui.openWindow来新开首页的,出了 ...