HarmonyOS web桥接原生代码方法

HarmonyOS
1天前
浏览
收藏 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)`)
  }

}
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS web原生交互
35浏览 • 1回复 待解决
HarmonyOS 接案列
12浏览 • 1回复 待解决
HarmonyOS Web js与原生交互
36浏览 • 1回复 待解决
HarmonyOS web原生交互的demo
86浏览 • 1回复 待解决
HarmonyOS 如何实现同步JS
236浏览 • 1回复 待解决
HarmonyOS 原生web端无法调通
10浏览 • 1回复 待解决
HarmonyOS web原生和H5如何交互?
562浏览 • 1回复 待解决
HarmonyOS Web组件UserAgent判断方法
34浏览 • 1回复 待解决
计划做直播课,原生Web-RTC是否支持?
2086浏览 • 1回复 待解决
HarmonyOS 代码延迟时间执行方法
487浏览 • 1回复 待解决
HarmonyOS 能否提供Web样例工程代码
249浏览 • 1回复 待解决
HarmonyOS 后台服务不到文件
34浏览 • 1回复 待解决