优势:
可快速迭代更新,无须App审核
体验流畅,毕竟是原生
减少开发成本,客户端和前端公用一套代码
理解webview
一个小型的浏览器内核,可以加载html网页,显示网页,是app中的一个组件
具体实现
前端做好静态页面(html、js、css),将文件交给客户端,一般是放在服务器上,提供一个服务器地址给客户端
客户端拿到前端静态页面、以文件的形式存储在app中
客户端在webview中使用file协议加载静态页面
hybrid 更新上线流程
主要打开app,回去服务端动态进行版本号对比,如果不一样,app会弹出提示用户更新,下载最新的包
前端干的活,维护服务端更新的静态资源包(html js css)
前端 服务端 客户端 三者协调
前端 客户端 如何通信
html js css 在手机上做的事情很有限,很多功能都需要app原生来做
微信公开开放给开发者的客户端能力,让js有能力操作手机的功能(js_sdk)
前端开发只需要调动js即可
比如一个新闻详情页面,前端如何获取内容
不能用ajax获取,第一跨域,第二速度慢
客户端获取新闻内容,前端js回调拿到内容再渲染
客户端可以在点击的同时获取数据(prefetch)
js必须在html页面渲染完成才能通过ajax获取数据
schema 协议
重用的协议有 http https ftp SMTP
file协议:本地文件,快
http(s)协议:网络加载、慢
前端调用客户端能力 - schema协议
协议规则:
微信的协议 (前面的协议名称可以自定义)
定义好以后,前端的js就可以和后端进行通信了
var iframe = docuemnt.createElement('iframe')
iframe.style.display = 'none'
iframe.src='weixin://dl/scan' //iframe 会访问微信的scan功能
var body = document.body || document.getElementByTagName('body')
body.appendChildren(iframe)
setTimeOut( () => {
body.removeChildren(iframe)
iframe = null
})
//如果要加上参数 和 回调函数 callBack,那么就这样写
window['_weixin_scan_callback'] = function(result){
alert(result)
}
iframe.src='weixin://dl/scan?k1=v1&k2=v2&k3=v3&callback=_weixin_scan_callback'
代码演示:客户端拿到参数执行对应的函数
function invokeScan() {
window['_invoke_scan_callback_'] = function (result) {
alert(result)
}
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
// iframe.src = 'weixin://dl/scan' // 重要!
iframe.src = 'weixin://dl/scan?k1=v1&k2=v2&k3=v3&callback=_invoke_scan_callback_'
var body = document.body
body.appendChild(iframe)
setTimeout(function () {
body.removeChild(iframe)
iframe = null
})
}schema协议调用封装成native.js
(function (window, undefined) {
// 调用 schema 的封装
function _invoke(action, data, callback) {
// 拼装 schema 协议
var schema = 'myapp://utils/' + action
// 拼接参数
schema += '?a=a'
var key
for (key in data) {
if (data.hasOwnProperty(key)) {
schema += '&' + key+'='+ data[key]
}
}
// 处理 callback
var callbackName = ''
if (typeof callback === 'string') {
callbackName = callback
} else {
callbackName = action + Date.now()
window[callbackName] = callback
}
schema += 'callback=callbackName'
// 触发
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = schema // 重要!
var body = document.body
body.appendChild(iframe)
setTimeout(function () {
body.removeChild(iframe)
iframe = null
})
}
// 暴露到全局变量
window.invoke = {
share: function (data, callback) {
_invoke('share', data, callback)
},
scan: function (data, callback) {
_invoke('scan', data, callback)
}
login: function (data, callback) {
_invoke('login', data, callback)
}
}
})(window)js代码调用客户端能力
document.getElementById('btn1').addEventListener('click', function () {
// invokeScan()
window.invoke.scan({}, function () {})
})
document.getElementById('btn2').addEventListener('click', function () {
window.invoke.share({
title: 'xxx',
content: 'yyy'
}, function (result) {
if (result.errno === 0) {
alert('分享成功')
} else {
alert(result.message)
}
})
})将以上封装的代码打包,叫做native.js,内置到客户端
客户端每次启动webview,都默认执行native.js
本地加载,免去网络加载的时间,速度更快
本地加载,没有网络请求,黑客看不到scheme协议、更安全
总结
通讯的基本形式:调用能力,传递参数、监听回调
对schema协议的理解和使用
调用schema代码的封装