需求:在正式与客户对接之前,老板要求先自己写一个demo来熟练流程
选型:以前没做过app,工作中使用uniapp写小程序和h5较多。故使用uniapp来写
a.app中
1.主页面
这里没有使用webview标签,用的是plus.webview.create方法(webview标签遇到问题,具体什么问题已经想不起来了,一两周前的事了)
//onload中
let _this = this
wv=plus.webview.create(`https:/xxxxxxxx.com/#channel=App&invite=${this.invite}&token=${this.token}`,"webview-1",{top:uni.getSystemInfoSync().statusBarHeight, //放置在titleNView下方。如果还想在webview上方加个地址栏的什么的,可以继续降低TOP值
height: uni.getSystemInfoSync().windowHeight -uni.getSystemInfoSync().statusBarHeight
})
var currentWebview = this.$scope.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
currentWebview.append(wv);//一定要append到当前的页面里!!!才能跟随当前页面一起做动画,一起关闭
plus.globalEvent.addEventListener('plusMessage', function(msg) {
let data = msg.data.args.data.arg
console.log('--收到h5的消息-:',JSON.stringify(data));
if(data){
switch(data.type) {
case 'outApp':
// 此时是需求是退出app
//app监听页面返回事件通知h5返回,h5中在首页时还返回就通知app退出
_this.back()
break;
case 'toService':
// 此时需求是从h5界面进入一个新的webview
console.log('h5界面进入一个新的webview')
uni.navigateTo({
url:'/subpages/onLine_service/onLine_service'
})
reak;
case 'toPayMiniProgram':
// 从app跳入支付小程序
console.log('跳往支付小程序',JSON.stringify(data.orderInfo))
try{
//sweixin的获取在下面
_this.sweixin.launchMiniProgram({
id: 'gh_xxxxxxxxxx',//原始id(不是appid),在微信公众平台-设置-基本设置
path: 'subpages/pay/pay?order=' + data.orderInfo,
type: 2//0:正式版,1:测试版,2:体验版
})
}catch(err){
console.log(JSON.stringify('err',err));
}
break;
}
}
});
this.getPlus()
此时在app中返回时直接显示的是再划一次退出app,而不是h5返回上一级页面。需要监听页面返回,通知h5返回上一个页面
//与onload同级
onBackPress(e) {
console.log('app监听到页面返回')
var pages = getCurrentPages()
var page = pages[pages.length - 1]
var currentWebview = page.$getAppWebview()
currentWebview.children()[0].evalJS('window.myHistory()')//调用h5的页面返回函数
return true; // 返回true 表示不执行返回键默认操作
},
methods中定义的一些方法
getPlus() {
//获取当前显示的webview
var pages = getCurrentPages()
var page = pages[pages.length - 1]
var currentWebview = page.$getAppWebview()
//调用H5+APP的扩展API
var shares=null;
let that = this
var pusher = plus.share.getServices(function(s){
shares={};
for(var i in s){
var t=s[i];
shares[t.id]=t;
}
that.sweixin=shares['weixin'];
}, function(e){
console.log("获取分享服务列表失败:"+e.message);
});
//放入当前的webview
currentWebview.append(pusher);
},
//.................................................
// 退出app。demo到这里改退出app了,如果只是退出webview的话调各自的关闭webview的方法
back() {
if(this.startTime == 0){
plus.nativeUI.toast('再按一次退出应用',2000)
this.startTime = new Date().getTime()
setTimeout(()=>{
this.startTime = 0
},2000)
}else if(new Date().getTime() - this.startTime < 2000){
// 两次返回间隔小于2000毫秒,退出应用
plus.runtime.quit();
}
},
2.副webview入口
h5中打开一个新的网页,如果有端的webview支持webview嵌套的话,就不需要了
代码和主webview差不多,只是不用监听plusMessage事件获得h5传递的消息和监听页面返回事件通知h5返回
3.小程序中支付完成后,返回app,给h5传参
//app的app.vue中的onshow中
let params = plus.runtime.arguments
if(params != ''){
try{
// 获取小程序支付完成后退回app时传递的参数
let type = params.split('&')[0].split('=')[1]
let data = params.split('&')[1].split('=')[1]
// console.log(JSON.stringify(type + '---' + data));
let pages = getCurrentPages()
let page = pages[pages.length - 1]
let currentWebview = page.$getAppWebview()
if(type == 'payBack'){
// 支付完成返回
// uni.setStorageSync('payBackData',data)
//调用h5中的一个方法来通知h5支付完成返回,可传参
currentWebview.children()[0].evalJS(`window.myPayBackData(${JSON.stringify(data)})`)
}else if(type == 'nopayBack'){
// 未支付返回
//调用h5中的一个方法来通知h5未支付返回,可传参
currentWebview.children()[0].evalJS(`window.myNopayBackData(${JSON.stringify(data)})`)
}
// 清除数据
plus.runtime.arguments = ''
}catch(e){}
}
b.h5中
支付时通知app跳转的方法
uni.webView.postMessage({
data:{
type:'toPayMiniProgram',
orderInfo:JSON.stringify(data)
}
})
收到app通知返回上一页的方法
//h5的app.vue的mounted里
//
window.myHistory = () => {
console.log('h5中的myHistory方法执行');
var path = this.$route.path//当前页面
if(path.indexOf('/pages/index/index') != -1 || path.indexOf('/pages/first/first') != -1 || path.indexOf('/pages/movie/movie') != -1){
window.AndroidView.getWaPiaoMessage(JSON.stringify({type:'outApp',dataName:'',data:'',}))
console.log('此时在首页,点击退出两次就退出app');
}else{
// 此时不在首页,点击物理按键的返回时,h5返回一级
uni.navigateBack({delta:1})
}
}
接受支付成功返回和未支付返回的方法页上面一样,只需把方法名和app调的方法名一致即可
c.实际对接时
和客户实际对接时才发现客户app用的是安卓原生还有ios端。上面的通信方法他收不到QAQ
可我app这也是第一次写啊,用uniapp写的时候还是一步一坑、一坑就得网上疯狂找解决方法。找安卓原生怎么和webview通信出来的全是安卓原生的写法,看不懂啊啊啊啊!
最后老板花了300大洋找人问,给的代码如下:
window.AndroidView.xxxxxxxMessage()
xxxxxxxMessage是需要安卓app暴露出来的方法。我们来调
不过这钱没白花,别看代码少。对接的时候客户的安卓开发人员不知道怎么写,又给了一个demo。
客户的人还不成功,问我AndroidView是什么。这我也不懂,就问300大洋,给回了一个是标签。又把他也拉到对接群里面作为我方的安卓技术支持,教客户的人
我听起来AndroidView和xxxxxxxMessage都是需要app来定义的
ios的代码是客户的ios开发人员给的
window.webkit.messageHandlers.xxxxxxxMessage.postMessag()
xxxxxxxMessage是需要iosapp暴露出来的方法。我们来调