我们有一个H5的小游戏链接,当放在uniapp开发的APP上面的时候出现Android手机全屏以后无法退出的问题。
具体是webview加载链接以后,打开H5里面的游戏手机会进入横向全屏状态,当退出游戏的时候游戏H5会通过webview的通信机制发送消息,告诉uanipp退出这个webview页面,iOS手机没问题,但是Android手机退出游戏的时候,接收到了H5发送的消息,但是只是退出了全屏状态,并没有退出这个webview页面,导致用户还需要按一下物理按键的返回才会退出。
经过多次测试,最终通过renderJs+iframe的方式才解决了问题,iframe可以避免出现退出两次才退出全屏状态的问题,但是无法接到H5发送的消息,必须结合renderjs才可以接到消息。
使用iframe来加载H5链接
<template>
<view>
<iframe id="iframe" :style="{ width: frameWidth + 'px', height: frameHeight + 'px' }" :src="typeUrl"
ref="iframe">
</iframe>
<!-- <web-view id="iframe" :style="{ width: frameWidth + 'px', height: frameHeight + 'px' }" :src="typeUrl"
ref="iframe">
</web-view> -->
</view>
</template>
正常的处理uniapp的方法,
receiveMessage
方法是接收renderjs发送的消息,动态iframe宽高实现横竖屏的大小控制
<script>
export default {
data() {
return {
typeUrl: "",
frameHeight: getApp().globalData.windowHeight,
frameWidth: getApp().globalData.windowWidth, };
},
onShow() {},
onLoad(e) {
},
methods: {
receiveMessage(arg) {
console.log("接收到renderjs回传的消息", arg);
// const action = data.data.data.arg.action;
// console.log('收到消息 arg', data.data.data.arg);
const action = arg.action;
console.log(" 收到消息action", action);
if (action == "back") {
this.back();
} else if (action == "share") {
this.uniShare(arg);
} else if (action == "LANDSCAPE") {
// #ifdef APP-PLUS
plus.screen.lockOrientation("landscape");
this.$nextTick(() => {
this.frameHeight = getApp().globalData.windowWidth;
this.frameWidth = getApp().globalData.windowHeight;
});
// #endif
} else if (action == "PORTRAIT") {
// #ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary");
this.$nextTick(() => {
this.frameHeight = getApp().globalData.windowHeight;
this.frameWidth = getApp().globalData.windowWidth;
});
// #endif
}
},
back() {
// 如果是H5,并且路由只有一级,为了避免返回不了首页
// #ifdef H5
const currentPages = getCurrentPages()
if (currentPages.length === 1) {
uni.reLaunch({
url: '/pages/home/index'
})
} else {
uni.navigateBack()
}
// #endif
// #ifdef APP-PLUS
uni.navigateBack();
// #endif
},
},
};
</script>
处理renderjs的方法,这里是为了能接收到H5发送来的消息,然后把消息内容转接到uniapp去处理
<script module="test" lang="renderjs">
export default {
mounted() {
window.addEventListener("message", this.receiveMsg, false);
},
methods: {
receiveMsg(data) {
console.log('收到renderjs消息', data);
const arg = data.data.data.arg;
console.log('收到消息 arg', data.data.data.arg);
if (arg) {
this.$ownerInstance.callMethod('receiveMessage', data.data.data.arg)
}
},
}
}
</script>