autoWebview.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /* eslint-disable */
  2. 'ui';
  3. // 一. 本地打包模式
  4. initUi('./index.html')
  5. /**
  6. * 初始化 UI
  7. * @param {string} htmlPath html文件的地址
  8. */
  9. function initUi (htmlPath) {
  10. ui.layout('<webview id="web" h="*" w="*" />')
  11. webViewExpand_init(ui.web)
  12. if (htmlPath.indexOf('http') === 0) {
  13. ui.web.loadUrl(htmlPath)
  14. } else {
  15. let path = 'file:' + files.path(htmlPath)
  16. ui.web.loadUrl(path)
  17. }
  18. }
  19. /**
  20. * 执行 js
  21. * @template T
  22. * @param {*} webViewWidget webview对象
  23. * @param {string} script 脚本
  24. * @param {(data:T)=>void} callback 回调函数
  25. */
  26. function callJavaScript (webViewWidget, script, callback) {
  27. try {
  28. console.assert(webViewWidget != null, 'webView控件为空')
  29. // runtimeLog(script.toString())
  30. webViewWidget.evaluateJavascript(
  31. 'javascript:' + script,
  32. new JavaAdapter(android.webkit.ValueCallback, {
  33. onReceiveValue: (val) => {
  34. if (callback) {
  35. callback(val)
  36. }
  37. },
  38. }),
  39. )
  40. } catch (e) {
  41. console.error('执行JavaScript失败')
  42. console.trace(e)
  43. }
  44. }
  45. /**
  46. * 执行 js
  47. * @template T
  48. * @param {string} code 欲执行的js代码
  49. * @param {(data:T)=>void} callback 回调函数
  50. */
  51. function callJs (code, callback) {
  52. callJavaScript(ui.web, code, callback)
  53. }
  54. function bridgeHandler_handle (cmd, args) {
  55. let ret
  56. // 执行 js代码
  57. if (args == '[code]') {
  58. ret = eval(cmd)
  59. } else {
  60. // 调用方法
  61. /** @type {Function} */
  62. let fun = this[cmd]
  63. if (!fun) {
  64. throw new Error('cmd= ' + cmd + ' 没有定义实现')
  65. }
  66. // 判断参数类型
  67. if (Array.isArray(args)) {
  68. ret = fun.apply(this, args)
  69. } else {
  70. ret = fun.call(this, args)
  71. }
  72. }
  73. return ret
  74. }
  75. function webViewExpand_init (webview) {
  76. webview.webViewClient = new JavaAdapter(android.webkit.WebViewClient, {
  77. /** 页面开始加载, 此时还没有加载 index.html 中的代码 */
  78. onPageStarted: (webView, url, favicon) => {
  79. },
  80. /** 页面加载完成, 在 window.onload 之后触发 */
  81. onPageFinished: (webView, curUrl) => {
  82. },
  83. onReceivedError: (webView, webResourceRequest, webResourceError) => {
  84. let url = webResourceRequest.getUrl()
  85. let errorCode = webResourceError.getErrorCode()
  86. let description = webResourceError.getDescription()
  87. console.trace(errorCode + ' ' + description + ' ' + url)
  88. },
  89. })
  90. webview.webChromeClient = new JavaAdapter(android.webkit.WebChromeClient, {
  91. /** 拦截 web console 消息 */
  92. onConsoleMessage: (consoleMessage) => {
  93. /** @type {string} */
  94. let msg = consoleMessage.message()
  95. let sourceId = consoleMessage.sourceId().split('/')
  96. let sourceIdStr = sourceId[sourceId.length - 1]
  97. let lineNumber = consoleMessage.lineNumber()
  98. let msgLevel = consoleMessage.messageLevel()
  99. if (msg.indexOf('jsbridge://') == 0) {
  100. let uris = msg.split('/')
  101. /** @type {{cmd:string, callId:number, args:any}} */
  102. let data = JSON.parse(java.net.URLDecoder.decode(uris[2], 'UTF-8'))
  103. let cmd = data.cmd
  104. let callId = data.callId
  105. let args = data.args
  106. runtimeLog('⭐ AJ 收到调用请求:', JSON.stringify(data).slice(0, 50))
  107. let result = null
  108. try {
  109. result = bridgeHandler_handle(cmd, args)
  110. } catch (e) {
  111. console.trace(e)
  112. result = {
  113. message: e.message,
  114. }
  115. }
  116. let callbackArgs = {
  117. callId: callId,
  118. args: result,
  119. }
  120. // 调用 web , 完成回调
  121. callJs(['auto.callback(', JSON.stringify(callbackArgs), ')'].join(''))
  122. } else {
  123. runtimeLog('📖 浏览器日志: %s [%s:%s] %s ', msgLevel, sourceIdStr, lineNumber, msg)
  124. }
  125. },
  126. })
  127. }
  128. /**
  129. * 框架 log
  130. * @description 注释方法中的代码就可以关闭所有的框架日志了.
  131. */
  132. function runtimeLog () {
  133. console.log.apply(this, arguments)
  134. }