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 | [引言]近年来随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员 ...
随机推荐
- ansible变量引用
1. 在/etc/ansible/hosts默认文件中定义变量 [test] 192.168.163.130 #[test:vars] #key=ansible 或者 192.168.163.130 ...
- 11.4 Android Studio如何设置代理
有些网络环境下,Android Studio下载无法下载依赖,这个时候就要配置代理,至于代理的问题,大家要自己解决. 获取代理信息 一般要获取如下信息: 地址:可以是域名和IP 端口: 代理类型:常用 ...
- JDBC:Statement问题
1.Statement问题 2.解决办法:通过PreparedStatement代替 实践: package com.dgd.test; import java.io.FileInputStrea ...
- IDEA的概述和IDEA的安装
开发工具概述 IDEA是一个专门针对Java的集成开发工具(IDE),由Java语言编写.所以,需要有JRE运行环境并配置好环境变量. 它可以极大地提升我们的开发效率.可以自动编译,检查错误.在公司中 ...
- Aborted wiping of zfs_member.1 existing signature left on the device.Aborting pvcreate on /dev/sda
看意思是有什么签名在上面,创建不了逻辑卷,确认数据备份的情况下执行对应的下面命令: wipefs --all --force /dev/sdax
- C语言课堂--现代编译环境搭建[2020年7月]
看过了很多专家吐槽目前的大学c语言教学问题多多: 教材难懂,消磨了学生的兴趣: 环境老旧,都2020了还有在用VC6甚至TurboC 2.0,语法不规范. 轮到自己上课,心想可不能再继续这样的c语言课 ...
- 建立二叉树的二叉链表存储结构(严6.70)--------西工大noj
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TreeNode ...
- 新建 Microsoft Office Word 文档 来源:牛客网
题目 链接:https://ac.nowcoder.com/acm/contest/28886/1015 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其 ...
- Centos7中配置NIS:用户账号管理
NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...
- 使用centos linux vps搭建jupyter notebook踩坑日记
今天我尝试用vps搭建在线jupyter notebook网站时遇到了这样一个问题: [W 21:48:07.243 NotebookApp] SSL Error on 9 ('171.115.101 ...