uni-app使用html5创建webview并通信
最近使用 uni-app 开发安卓端的 App,因为要嵌入一个原本已经开发完的系统,打算使用 web-view 的方式进行嵌入。
因为项目工期比较紧,所以是两个前端并行开发,最后再合到一起。结果就是这个过程中出问题了…
需求
需求方面是:A同学负责通讯方面的工作,所以页面应该在首页就被挂载上去,这样一来启动系统的时候就注册了通讯模块,不影响收发信息。
B同学负责其他部分,在首页展示系统内部的统计数据,可以算是一个安卓端的简易大屏。
原本A同学的方案是在系统页面上创建一个 web-view,然后嵌入系统。这样一来也不影响B同学开发新系统。
问题
结果整合代码的时候才发现,web-view标签 是自动铺满整个页面的,而且是无法隐藏的。
这就尴尬了,App进来以后直接看到的就是 A同学的通讯页面,无法看到B同学的大屏了。
问题抛到了我手里,我经过一番简单的调研,再加上一顿猛如虎的操作,回复他们说:无解!
uni-app 中内置的 web-view 标签本身没有隐藏的API,在 web-view 标签外增加 view 标签,绑定 v-show 方法不生效。
只能绑定 v-if 生效,但是绑定 v-if=false 的时候相当于 web-view 直接被销毁了,会导致通讯模块收不到信息。
解决
好在天无绝人之路,uni-app 官方文档中表示:在html5+中其实存在 web-view 的API,能够操作窗口的大小。
那么既然能够操作窗口的大小,肯定也能够控制显隐。
解决方案为使用 html5+ 中的 create 方法创建 web-view。
createWebView() {
let that = this;
if (this.webviewIns) return;
this.webviewIns = plus.webview.create(
'http://192.168.25.110',
'1008610010'// ID(必须唯一)
{
top: '24px',
bottom: '0px',
width: '300px',
height: '600px',
scrollIndicator: 'none',
scalable: false
}
);
// 设置页面默认隐藏
this.webviewIns.hide();
}
这时候已经成功创建了 web-view 并且处于隐藏状态,不耽误传参。
但是又遇到了一个问题,web-view无法与uni-app通信。
uni-app 官方提供的方法是使用 uni.postMessage 方法,但是我在 通讯系统中插入了这个方法,不报错,并且显示发送消息成功,uni-app 这边却无法接收到。
又使用 evalJS 方法插入相应的脚本,但是也没有反应。同样是发送成功,但是接收不到。
详细看了看 uni-app 的官方文档,分析 web-view 标签上绑定的 @message 方法应该是经过特殊封装的,能够捕获到 view-view 内使用 uni.postMessage 方法发送的数据。
但是由于我现在使用 plus.web-view.create 创建窗口,绕过了uni-app 所以即便是绑定 message 也无效了。
所以采用 html+ 原生方法发送数据,在 web-view 中使用 plus.webview.postMessageToUniNView 方法发送数据。
在 uni-app 端使用 plus.globalEvent.addEventListener 接收数据。
// 发送数据
pushMessage() {
plus.webview.postMessageToUniNView({
type: 'tpUniAPP',
args: {
args1: 'test123'
}
}, '__uniapp__service');
}
接收数据方法写在 createWebView 方法内。
// 接收数据
createWebView() {
let that = this;
if (this.webviewIns) return;
// 创建一个新的 WebView
this.webviewIns = plus.webview.create(
...
);
// web-view加载完成
this.webviewIns.addEventListener('loaded', () => {
plus.globalEvent.addEventListener('plusMessage', (message)=>{
let data = message?.data?.args?.data;
if(data?.name === 'postMessage') {
if (data?.arg?.type === 'show') {
// 显示
that.webviewIns.show();
}
if (data?.arg?.type === 'hide') {
// 隐藏
that.webviewIns.hide();
}
}
})
});
this.webviewIns.hide();
},
结论
目前主要解决了两个问题:
-
web-view 大小、显隐不可控问题。 -
web-view 与 uni-app 通信问题。
发送数据方法可以卸载 Pinia 的公共方法中,或者使用 EventBus,统一处理。
Ps: 第二个问题解决方案不是太优雅,如果有兄弟有更好的方案可以分享一下。

👇点击下方关注李剑一,获取更多资讯文章,了解更多的前沿科技,还可以获得免费的编程学习路线、面试题库。
夜雨聆风
