Js与app内部通信的实现方式
准则: APP执行js函数,js项犯规数据给APP,一律通过执行函数异步地进行,反过来js执行app函数,app想返回数据给js,也一律通过执行回调函数异步进行。
webView.loadUrl("javascript:sayHello()")
实际应用:
因为通过这种方式执行js函数这个函数需要在js的全局中才能正常运行,所以实际编码中不会直接这样执行,而是有一个统一的入口。
webView.loadUrl("javascript:appCallJs('test')")
js端的代码实现
import appBridge from './appBridge.js'
export default {
install: function (Vue) {
window.appCallbackJs = appBridge.appCallbackJs
window.appCallJs = appBridge.appCallJs
Vue.appBridge = appBridge
Vue.prototype.$appBridge = appBridge
}
}
appBridge.js 内容:
import appCallJsFunction from './appCallJsFunction/index.js'
let _queueCallbacks = []
// 获取当前运行环境为Android或者ios或者浏览器
let getRunEnv = function () { // 这里暂时写死为Android,请和app开发人员约定一个获取运行环境的函数,并通过这个函数获取运行环境
return {
system: 'Android', // Android平台
env: 'App' // app环境
}
}
export default {
jsCallApp: function (funName, parameter, successCallback, errorCallback) {
var key = this._addQueueCallbacks(successCallback, errorCallback)
try {
parameter = JSON.stringify(parameter)
} catch {
console.log('')
}
if (getRunEnv().system === 'Android') {
window.JsCallAndroid.execute(funName, parameter, key)
} else {
window.webkit.messageHandlers['execute'].postMessage({
'funName': funName,
'parameter': parameter,
'key': key
})
}
},
appCallJs: function (funName, parameter, key) { // funName 执行的方法名 parameter参数
function jsCallbackApp (key, successOrError, parameter) {
try {
parameter = JSON.stringify(parameter)
} catch {
console.log('')
}
if (getRunEnv().system === 'Android') {
window.JsCallAndroid.jsCallbackApp(key, successOrError, parameter)
} else {
window.webkit.messageHandlers['jsCallbackApp'].postMessage({
'key': key,
'successOrError': successOrError,
'parameter': parameter
})
}
}
appCallJsFunction[funName](parameter, function (successOrError, jsParameter) {
jsCallbackApp(key, successOrError, jsParameter)
})
},
appCallbackJs: function (key, successOrError, parameter) {
for (var i = 0; i < _queueCallbacks.length; i++) {
if (_queueCallbacks[i].key === key) {
try {
parameter = JSON.parse(parameter)
} catch {
console.log('')
}
if (successOrError === 'success') {
_queueCallbacks[i].success(parameter)
} else if (successOrError === 'error') {
_queueCallbacks[i].error(parameter)
}
}
}
},
_queueCallbacks: [],
_addQueueCallbacks: function (pSuccessCallback, pErrorCallback) {
var key = this._getUuid()
_queueCallbacks.push({
success: pSuccessCallback,
error: pErrorCallback,
key: key
})
return key
},
_getUuid: function (len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
var uuid = []
radix = radix || chars.length
if (len) {
for (var i = 0; i < len; i++) {
uuid[i] = chars[0 | Math.random() * radix]
}
} else {
var r = null
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
uuid[14] = '4'
for (var j = 0; j < 36; j++) {
if (!uuid[j]) {
r = 0 | Math.random() * 16
uuid[j] = chars[(j === 19) ? (r & 0x3) | 0x8 : r]
}
}
}
return uuid.join('')
}
}
appCallJsFunction
export default {
test: function (parameter, callFun) {
console.log('app调用了js的方法' + parameter)
var jsParameter = {
'name': '来至js的参数'
}
callFun('success', jsParameter)
}
}