HarmonyOS web桥接原生代码方法

HarmonyOS
2024-12-25 15:27:33
1464浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
put_get

示例参考如下:

pluginPage.ets:import { Logger } from '@hw-agconnect/hmcore';
// common/PluginPage
import router from '@ohos.router';
import web_webview from '@ohos.web.webview';
import { BusinessError } from '@kit.BasicServicesKit';
import webview from '@ohos.web.webview';
import buffer from '@ohos.buffer';
import { util } from '@kit.ArkTS';
import { common } from '@kit.AbilityKit';

const TAG = '[PluginPage]'

interface UrlParams {
  url: string;
  methodList: Array<string>
}

class testClass {
  constructor() {
  }

  GreeApp(cls:string): void {
    let obj:ESObject = JSON.parse(cls);
    let clsName:string = obj.clsName;
    let func:string = obj.funName;
    let funData:object = obj.funData;
    let funCallback:string = obj.funCallback
    let path:string = `../apis/${clsName}`;
    Logger.info(TAG, "clsName = "+cls);
    import(path).then((ns: ESObject) => {
      let sys: ESObject = new ns[clsName]();
      sys[func](funData,funCallback);
    })
      .catch((err:BusinessError) => {
        console.log('err12344:'+err)
      })
    // {"clsName":"System","funName":"getSystemInfo","funData":{},
    // "funCallback":"GreeApp_cb_1720515357602.0.7082100644892653"}

  }

  getInfo(param:ESObject) {
    console.log('getInfo111:'+JSON.stringify(param))
    let str:string=param.arguments[0];
    let callback:string=param.callback;
    let controller=AppStorage.get('controller') as WebviewController;
    controller.runJavaScript(`pluginsInterfaceCallBack1("${callback}",'{"timezoneOffset":"+8","mainMac":"","subdivCode":"","host":"","fullstatueJson":"","name":"qw"}')`)

  }

  finishLoad() {
    Logger.info(TAG, "finishLoad")
  }


  onCallBack() {
    Logger.info(TAG, "onCallBack = ");
  }

  sendDataToDevice(){

  }
}

@Entry({ routeName: 'PluginPage' })
@Component
export struct PluginPage {
  controller: WebviewController = new web_webview.WebviewController()
  @State url: string = '';
  // 声明需要注册的对象
  @State testObj: testClass = new testClass();
  // @State testObj2: testClass = new testClass();
  methodList: Array<string> = (router.getParams() as UrlParams).methodList;
  @State jsContent:string='';
  private context=getContext(this) as common.UIAbilityContext;
  ports: webview.WebMessagePort[] = [];
  webviewJavascriptBridge =
    "(function(){if(window.WebViewJavascriptBridge){return}var receiveMessageQueue=[];var messageHandlers={};var responseCallbacks={};var uniqueId=1;function init(messageHandler){if(WebViewJavascriptBridge._messageHandler){throw new Error('WebViewJavascriptBridge.init called twice');}WebViewJavascriptBridge._messageHandler=messageHandler;var receivedMessages=receiveMessageQueue;receiveMessageQueue=null;for(var i=0;i<receivedMessages.length;i++){_dispatchMessageFromNative(receivedMessages[i])}}function send(data,responseCallback){_doSend('jsbridge','send',data,responseCallback)}function registerHandler(handlerName,handler){messageHandlers[handlerName]=handler}function callHandler(handlerName,data,responseCallback){_doSend('jsbridge',handlerName,data,responseCallback)}function callHandlerWithModule(moduleName,handlerName,data,responseCallback){_doSend(moduleName,handlerName,data,responseCallback)}function _doSend(moduleName,handlerName,message,responseCallback){var callbackId;if(typeof responseCallback==='string'){callbackId=responseCallback}else if(responseCallback){callbackId='cb_'+(uniqueId++)+'_'+new Date().getTime();responseCallbacks[callbackId]=responseCallback}else{callbackId=''}try{var evalStr1='window.'+moduleName+'.';if(moduleName=='jsbridge'&&handlerName!='response'){evalStr1+='handler'}else{evalStr1+=handlerName}var fn=eval(evalStr1)}catch(e){console.log(e)}if(typeof fn==='function'){var evalStr='window.'+moduleName;var fnwindow=eval(evalStr);var responseData;if(moduleName=='jsbridge'&&handlerName!='response'){responseData=fn.call(fnwindow,handlerName,JSON.stringify(message),callbackId)}else{responseData=fn.call(fnwindow,JSON.stringify(message),callbackId)}if(responseData){responseCallback=responseCallbacks[callbackId];if(!responseCallback){return}responseCallback(responseData);delete responseCallbacks[callbackId]}}}function _dispatchMessageFromNative(messageJSON){setTimeout(function(){var message=JSON.parse(messageJSON);var responseCallback;if(message.responseId){responseCallback=responseCallbacks[message.responseId];if(!responseCallback){return}responseCallback(message.responseData);delete responseCallbacks[message.responseId]}else{if(message.callbackId){var callbackResponseId=message.callbackId;responseCallback=function(responseData){_doSend('jsbridge','response',responseData,callbackResponseId)}}var handler=WebViewJavascriptBridge._messageHandler;if(message.handlerName){handler=messageHandlers[message.handlerName]}try{handler(message.data,responseCallback)}catch(exception){if(typeof console!='undefined'){console.log(\"WebViewJavascriptBridge: WARNING: javascript handler threw.\",message,exception)}}}})}function _handleMessageFromNative(messageJSON){if(receiveMessageQueue){receiveMessageQueue.push(messageJSON)}_dispatchMessageFromNative(messageJSON)}var WebViewJavascriptBridge=window.WebViewJavascriptBridge={init:init,send:send,registerHandler:registerHandler,callHandler:callHandler,callHandlerWithModule:callHandlerWithModule,_handleMessageFromNative:_handleMessageFromNative};console.log(\"start jsbridge ...\");var doc=document;var readyEvent=doc.createEvent('Events');readyEvent.initEvent('WebViewJavascriptBridgeReady');readyEvent.bridge=WebViewJavascriptBridge;doc.dispatchEvent(readyEvent);console.log(\"end jsbridge ...\")})();";

  aboutToAppear(){
    web_webview.WebviewController.setWebDebuggingAccess(true);
    const params = router.getParams() as UrlParams;
    this.url = params.url +
      '?mac=9424b8a49d7a&data=[3,0,1,1,0,0,0,28,0,0,1,0,0,0,1,"7e000035",1,0,0,5,0,65,0,0,0,0,0,0]&functype=0&mainMac=&vender=7e000035';
  }

  build() {
    Column() {
      Web({ src: this.url, controller: this.controller })// 将对象注入到web端
        .javaScriptProxy({
          object: this.testObj,
          name: "gree",
          methodList: ['onCallBack',"GreeApp", 'getInfo', 'PluginInterface', 'sendDataToDevice',"getSystemInfo",'finishLoad'],
          // methodList: this.methodList,
          controller: this.controller
        })
        .domStorageAccess(true)

        .onPageEnd((event) => {
          // 推荐在此事件中执行JavaScript脚本
          Logger.info(TAG, 'onPageEnd');
          if (event) {
            Logger.info(TAG, 'onPageEnd url:' + event.url);
          }
          getContext(this).resourceManager.getRawFileContent('WebViewJavascriptBridge.js', (err, data) => {
            const str = buffer.from(data.buffer).toString()
            this.controller.runJavaScript(str);
            this.controller.runJavaScript(`document.dispatchEvent(new Event('deviceready'))`)
            AppStorage.setOrCreate('controller', this.controller);
            console.log('controller1111:' + JSON.stringify(this.controller))
          })

        })
        .javaScriptAccess(true)
    }
  }

  createWebMessagePorts() {
    try {
      // 1、创建两个消息端口。
      this.ports = this.controller.createWebMessagePorts();
      this.ports.forEach((port, index) => {
        Logger.info(TAG, 'index = ' + index);
        Logger.info(TAG, 'port = ' + JSON.stringify(port));
      })
      if (this.ports && this.ports[1]) {
        Logger.info(TAG, 'ports存在');
      } else {
        Logger.info(TAG, `ports is null, Please initialize first`);
      }
      // 2、在应用侧的消息端口(如端口1)上注册回调事件。
      this.ports[0].onMessageEvent((result: webview.WebMessage) => {
        Logger.info(TAG, '在应用侧的消息端口(如端口1)上注册回调事件');
        let msg = 'Got msg from HTML:';
        if (typeof (result) === 'string') {
          Logger.info(TAG, `received string message from html5, string is: ${result}`);
          msg = msg + result;
        } else if (typeof (result) === 'object') {
          if (result instanceof ArrayBuffer) {
            Logger.info(TAG, `received arraybuffer from html5, length is: ${result.byteLength}`);
            msg = msg + 'lenght is ' + result.byteLength;
          } else {
            Logger.info(TAG, 'not support');
          }
        } else {
          Logger.info(TAG, 'not support');
        }
        // this.receivedFromHtml = msg;
      })
      // 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
      this.controller.postMessage('__init_port__', [this.ports[0]], '*');
    } catch (error) {
      Logger.info(TAG, `ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
    }
  }
}

plugin/index.ets(动态导入的类需要把路径加进来):
export { PluginPage } from './src/main/ets/components/PluginPage'
export { PluginUtils } from './src/main/ets/util/PluginUtils'
export { System } from './src/main/ets/apis/System'
export { UserData } from './src/main/ets/apis/UserData'

build-profile.json5(动态导入的类需要把路径加到source里面):
{
  "apiType": "stageMode",
"buildOption": {
  "arkOptions": {
    "runtimeOnly": {
      "sources": [
      './src/main/ets/apis/System.ets',
      './src/main/ets/apis/UserData.ets'
      ],
      "packages": []
    }
  }
},
  "buildOptionSet": [
  {
    "name": "release",
  "arkOptions": {
    "obfuscation": {
      "ruleOptions": {
        "enable": true,
        "files": [
        "./obfuscation-rules.txt"
        ]
      },
      "consumerFiles": [
      "./consumer-rules.txt"
      ]
    }
  },
  },
  ],
  "targets": [
  {
    "name": "default"
  },
  {
    "name": "ohosTest"
  }
  ]
}

apis/System.ets:

export class System {
  public test: string = ''
  constructor() {

  }

  getSystemInfo(funData: object, callback: string) {
    console.log('funData1111:' + JSON.stringify(funData))
    console.log('getSystemInfo11111:' + callback)
    let param: ESObject = {};
    let controller=AppStorage.get('controller') as WebviewController;
    controller.runJavaScript(`GreeAppCallback("${callback}",{system:'xxx',version:'5.7.12'})`)
  }

}

apis/UserData.ets:

export class UserData {
  // controller: WebviewController = new web_webview.WebviewController()
  public test: string = ''

  constructor() {

  }

  getUserInfo(funData: object, callback: string) {
    console.log('funData1111:' + JSON.stringify(funData))
    console.log('getSystemInfo11111:' + callback)

    let controller=AppStorage.get('controller') as WebviewController;
    controller.runJavaScript(`GreeAppCallback("${callback}",{nname:'202324'})`)
  }

  getHomeId(funData: object, callback: string) {
    console.log('funData1111:' + JSON.stringify(funData))
    console.log('getSystemInfo11111:' + callback)
    let param: ESObject = {};

    let controller=AppStorage.get('controller') as WebviewController;
    controller.runJavaScript(`GreeAppCallback("${callback}",15545)`)
  }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
分享
微博
QQ
微信
回复
2024-12-25 17:21:28


相关问题
如何鸿蒙原生与H5之间的交互?
644浏览 • 2回复 已解决
HarmonyOS H5
937浏览 • 1回复 待解决
HarmonyOS webview方式如何编写
757浏览 • 1回复 待解决
HarmonyOS web原生交互
641浏览 • 1回复 待解决
HarmonyOS 接案列
511浏览 • 1回复 待解决
HarmonyOS Web js与原生交互
1236浏览 • 1回复 待解决
HarmonyOS webview与原生交互方法重名
662浏览 • 1回复 待解决
HarmonyOS web原生交互的demo
599浏览 • 1回复 待解决
HarmonyOS 如何实现同步JS
686浏览 • 1回复 待解决
HarmonyOS 原生web端无法调通
1000浏览 • 1回复 待解决
HarmonyOS web原生和H5如何交互?
1493浏览 • 1回复 待解决
HarmonyOS web组件注入JS代码
621浏览 • 1回复 待解决
HarmonyOS 后台服务不到文件
864浏览 • 1回复 待解决
HarmonyOS 能否提供Web样例工程代码
980浏览 • 1回复 待解决