使用plus.webview.create创建新窗体在打开tabbar页面的时候会闪退
使用plus.webview.create创建新窗体在打开tabbar页面的时候会闪退
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | windows11 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
PC开发环境操作系统版本号:windows11
HBuilderX类型:正式
HBuilderX版本号:4.87
手机系统:Android
手机系统版本号:Android 12
手机厂商:模拟器
手机机型:oppo
页面类型:vue
vue版本:vue2
打包方式:云端
项目创建方式:HBuilderX
示例代码:
```html
<template>
<!-- <web-view :src="payLink">
</web-view> -->
</template>
<script>
import common from '@/common/common.js';
export default {
data() {
return {
proxyUrl: '',
payLink: '',
orderNum: '',
checkInterval: null,
paymentCompleted: false,
wv:null,
tt:null
}
},
onLoad(options) {
console.log('支付页面参数:', options)
if(options && options.data){
const data = JSON.parse(options.data);
this.payLink = data.payLink || '';
this.orderNum = data.orderNum || '';
// 提取订单号
this.extractOrderNum();
try{
if(plus){
setTimeout(() => {
var w=plus.nativeUI.showWaiting();
this.wv = plus.webview.create(
data.payLink,
'myWebview2',
{
top: '80px',
bottom: '0px',
width: '100%',
height: '100%',
zindex: 100,
}
);
this.wv.show('none', 0);
this._isActive = true;
const self = this;
this.wv.addEventListener('loaded', function(){
w.close();
w=null;
}, false);
this.wv.addEventListener('error', function(e) {
w.close();
uni.showModal({
title: '加载失败',
content: '请检查网络或链接地址',
showCancel: false
});
}, false);
this.wv.addEventListener('close', (e) => {
uni.switchTab({
url:'/pages/user/user',
success(res){
uni.showToast({
title: "跳转成功",
icon: 'none'
});
},
fail(err){
uni.showToast({
title: JSON.stringify(err),
icon: 'none',
duration:10000
});
}
});
// uni.showToast({
// title: 'Webview ID:'+this.wv.id +'已销毁',
// icon: 'none'
// });
this.wv = null;
}, false);
}, 300); // 100ms 延迟
}
}catch(error){
// uni.showModal({
// title: 'error',
// content: JSON.stringify(error),
// showCancel: false,
// success: (res) => {
// }
// });
}
}
},
onBackPress() {
plus.webview.close('myWebview2', 'none');
return false;
},
methods: {
// 提取订单号
extractOrderNum() {
},
},
mounted() {
common.setTopLeftBtn(this);
}
}
</script>
操作步骤: 从tabbar页面 pages/user/user 到 pages/userCenter/order 再到 pages/checkout/pay 页面中创建plus.webview.create,再回退到tabbar页面 pages/user/user时App闪退。
预期结果: 正常回到tabbar页面
实际结果: app闪退
bug描述: 使用plus.webview.create创建新窗体,在打开tabbar页面的时候会闪退
该bug反馈内容基本完整但存在关键缺失:BUG描述未说明具体触发场景(如从哪个页面跳转tabbar时闪退),缺少崩溃日志;代码示例中混用了小程序API(this.$mp.page.$getAppWebview())和App API,在App环境中不应使用$mp对象,且未处理webview与tabbar页面的层级关系;复现步骤过于笼统(“随便找个页面”),无法精准复现;分类信息中HBuilderX 4.87版本较旧(当前最新版更高),可能已修复此问题。
经分析,该问题不完全是bug:首先,用户错误地在App环境使用小程序专属API $mp,正确做法应通过plus.webview.currentWebview()获取当前webview;其次,根据页面跳转规则,tabbar页面必须用switchTab跳转,但webview关闭后直接调用uni.switchTab可能因页面栈异常导致闪退,尤其在旧版本中。建议:1. 升级HBuilderX至最新版;2. 移除$mp相关代码,改用plus.webview.currentWebview().append(this.wv);3. 在webview的close事件中增加延迟或检查当前页面栈状态再跳转;4. 参考webview通信文档规范使用。该问题更可能是API误用而非底层bug,旧版本兼容性不足加剧了现象。 内容为 AI 生成,仅供参考
apk压缩包上传附件上传不了啊,提示压缩包太大了
根据你提供的代码和问题描述,这是一个典型的 Webview 与 TabBar 页面交互导致的闪退问题。主要原因是在 Webview 的 close 事件中使用了 uni.switchTab 跳转 TabBar 页面,这会造成页面栈管理冲突。
问题分析:
- 事件监听器作用域问题:在
close事件监听器中使用了this.wv = null,但这里的this指向的是 Webview 对象而非 Vue 组件实例,可能导致后续操作异常。 - TabBar 页面跳转时机不当:在 Webview 关闭事件中直接跳转 TabBar 页面,可能与页面销毁流程产生冲突。
- Webview 生命周期管理:可能存在 Webview 未完全销毁时就开始页面跳转的情况。
解决方案:
修改 close 事件监听器的实现方式:
// 在onLoad中修改close事件监听
const self = this;
this.wv.addEventListener('close', function(e) {
// 使用setTimeout确保在下一个事件循环中执行
setTimeout(() => {
// 先确保webview完全销毁
if (self.wv) {
plus.webview.close(self.wv.id);
self.wv = null;
}
// 使用reLaunch或redirectTo代替switchTab
uni.reLaunch({
url: '/pages/user/user',
success: function() {
console.log('跳转到TabBar页面成功');
},
fail: function(err) {
console.error('跳转失败:', err);
}
});
}, 100);
}, false);
关键修改点:
- 使用箭头函数或保存this引用:确保在事件回调中能正确访问Vue实例
- 添加延迟执行:使用
setTimeout确保Webview完全关闭后再执行跳转 - 使用reLaunch代替switchTab:
reLaunch会关闭所有页面并打开新页面,避免页面栈冲突 - 显式关闭Webview:在跳转前确保Webview被正确关闭
替代方案:
如果仍需使用 switchTab,可以尝试在页面 onHide 或 onUnload 生命周期中处理Webview的销毁:
onUnload() {
if (this.wv) {
plus.webview.close(this.wv.id);
this.wv = null;
}
}

