js与app内部通讯的实现方式

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)
  }
}

你可能感兴趣的:(js与app内部通讯的实现方式)