0
点赞
收藏
分享

微信扫一扫

HarmonyOS:前端页面调用应用侧函数

一、 需求场景

有时候,前端页面需要通过调用应用的函数获取数据,例如获取应用的版本信息、用户登录信息等应用数据。

二、实现方案

开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。
注册应用侧代码有两种方式:

  • 方式一:种在Web组件初始化调用,使用javaScriptProxy()接口。
  • 方式二:在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口,需要和deleteJavaScriptRegister接口配合使用,防止内存泄漏。

三、使用javaScriptProxy()接口使用示例

将TestClass类里的方法注册在前端页面中, 这些函数可以在前端页面触发运行。

3.1、示例代码

testArkWebH5CallNative.html

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
    .btn {
        width: 600px;
        height: 100px;
        font-size: 40px;
        margin-top: 60px;
    }
</style>
<body>
<strong style="font-size:40px;">调用原生方法</strong>
</br>
<button class="btn" id="callArkTSTestStr" type="button" onclick="callArkTSTestStr()">callArkTSTestStr方法</button>

</br>
<button class="btn" id="callArkTSTestArry" type="button" onclick="callArkTSTestArry()">callArkTSTestArray方法</button>

</br>
<button class="btn" id="callArkTStoString2" type="button" onclick="callArkTStoString2()">callArkTStoString2方法</button>

</br>
<button class="btn" id="callArkTSasyncTest" type="button" onclick="callArkTSasyncTest()">callArkTStoString2方法</button>
<p style="font-size:40px;" id="resultData"></p>

<script>
    function callArkTSTestStr() {
       let str = testObjName.testStr();
       document.getElementById("resultData").innerHTML = str;
       console.info('H5 callArkTSTestStr 调用原生 testStr 方法返回的数据:' + str);
    }

    function callArkTSTestArry() {
        let arrayNum = testObjName.testArray();
        console.info('H5 callArkTSTestArry 调用原生 testArray 方法返回的数据:' + arrayNum);
    }

    function callArkTStoString2() {
        testObjName.toString2("这是来自H5数据");
        console.info('H5 callArkTStoString2 调用原生 toString2 方法 传递的数据');
    }

    function callArkTSasyncTest() {
        testObjName.asyncTest("这是来自H5调用 asyncTest 方法传递的数据");
        console.info('H5 callArkTSasyncTest 调用原生 asyncTest 方法');
    }
</script>
</body>
</html>

TestArkWebH5CallNative.ets

import { webview } from '@kit.ArkWeb'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'

class TestClass {
  constructor() {
  }

  testStr(): string {
    return "原生 testClass 里 test 方法返回的数据";
  }

  testArray(): Array<Number> {
    return [1, 2, 3, 4, 5, 6];
  }

  toString(): void {
    console.log('toString 方法 Web Component toString');
  }

  toString2(param: String): void {
    console.log('toString2 方法  Web Component toString param:' + param);
  }

  asyncTest(data: string): void {
    console.log("async data:" + data);
  }
}

const JavaScriptProxy_NAME = "testObjName";

@Entry
@Component
struct TestArkWebH5CallNative {
  @State message: string = '前端页面调用应用侧函数';
  @State testClass: TestClass = new TestClass()
  webviewController: webview.WebviewController = new webview.WebviewController()

  aboutToAppear(): void {
    try {
      webview.WebviewController.setWebDebuggingAccess(true);
    } catch (error) {
      console.error(`aboutToAppear webview 配置Web开启调试模式出错了:ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
    }
  }

  build() {
    Column() {
      Button('deleteJavaScriptRegister').fontColor(Color.Black).fontSize(20).onClick((_event) => {
        try {
          this.webviewController.deleteJavaScriptRegister(JavaScriptProxy_NAME);
        } catch (error) {
          console.error(`移除 testObjName 发生异常 ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
        }
      })
      Web({ src: $rawfile('testArkWebH5CallNative.html'), controller: this.webviewController })// 将对象注入到web端
        .javaScriptAccess(true)
        .javaScriptProxy({
          object: this.testClass,
          name: JavaScriptProxy_NAME,
          methodList: ["testStr", "testArray", "toString", "toString2"],
          controller: this.webviewController,
          // 可选参数
          asyncMethodList: ["asyncTest"],
        })
    }
    .height('100%')
    .width('100%')
  }
}

四、应用侧使用registerJavaScriptProxy()接口注册

将testClass2类里的方法注册在前端页面中, 这些函数可以在前端页面触发运行。

4.1 代码、

testArkWebH5CallNative2.html

<!DOCTYPE html>
<html>
<style>
    .btn {
        width: 600px;
        height: 100px;
        font-size: 40px;
        margin-top: 60px;
    }
</style>
<body>
<button class="btn" type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
        let str = testObjName.test();
        document.getElementById("demo").innerHTML = str;
       console.info('H5 callArkTS 调用原生 test 方法返回的数据:' + str);
    }
</script>
</body>
</html>

TestArkWebH5CallNative2.ets

import { webview } from '@kit.ArkWeb'
import { BusinessError } from '@kit.BasicServicesKit';

class testClass2 {
  constructor() {
  }

  test(): string {
    return "原生 testClass2 类的 test 方法返回的数据 ";
  }

  toString(): void {
    console.log('Web Component toString');
  }
}

@Entry
@Component
struct TestArkWebH5CallNative2 {
  @State message: string = 'Hello World';
  @State webviewController: webview.WebviewController = new webview.WebviewController();
  @State testObj: testClass2 = new testClass2();
  private registerJavaScriptProxySucceed: boolean = false;

  aboutToAppear(): void {
    webview.WebviewController.setWebDebuggingAccess(true);
  }

  build() {
    Column() {
      Button("refresh")
        .margin({ top: 20 })
        .onClick(() => {
          if (!this.registerJavaScriptProxySucceed) {
            console.log("请先调用 registerJavaScriptProxy 方法")
            return
          }
          try {
            this.webviewController.refresh();
            console.log("调用了 refresh 方法")
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('Register JavaScript To Window')
        .margin({ top: 20 })
        .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"],
              // 可选参数, asyncMethodList
              []
            );
            this.registerJavaScriptProxySucceed = true;
            console.log("调用了 registerJavaScriptProxy 方法");
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('deleteJavaScriptRegister')
        .margin({ top: 20 })
        .onClick(() => {
          try {
            this.webviewController.deleteJavaScriptRegister("testObjName");
            console.log("调用了 deleteJavaScriptRegister 方法")

          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Web({ src: $rawfile('testArkWebH5CallNative2.html'), controller: this.webviewController })
    }
    .height('100%')
    .width('100%')
  }
}

举报

相关推荐

0 条评论