瑞星 发表于 2024-11-2 17:43:47

鸿蒙NEXT版实战开发:前端页面调用应用侧函数(前端页面JavaScript)

往期鸿蒙全套实战出色文章必看内容:



[*] 鸿蒙开发核心知识点,看这篇文章就够了
[*] 最新版!鸿蒙HarmonyOS Next应用开发实战学习门路
[*] 鸿蒙HarmonyOS NEXT开发技能最全学习门路指南
[*] 鸿蒙应用开发实战项目,看这一篇文章就够了(部分项目附源码)
前端页面调用应用侧函数

开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。
注册应用侧代码有两种方式,一种在Web组件初始化调用,使用javaScriptProxy()接口。别的一种在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口。
在下面的示例中,将test()方法注册在前端页面中, 该函数可以在前端页面触发运行。


[*] javaScriptProxy()接口使用示例如下。
// xxx.ets
import { webview } from '@kit.ArkWeb';

class testClass {
constructor() {
}

test(): string {
    return 'ArkTS Hello World!';
}
}

@Entry
@Component
struct WebComponent {
webviewController: webview.WebviewController = new webview.WebviewController();
// 声明需要注册的对象
@State testObj: testClass = new testClass();

build() {
    Column() {
      // Web组件加载本地index.html页面
      Web({ src: $rawfile('index.html'), controller: this.webviewController})
      // 将对象注入到web端
      .javaScriptProxy({
          object: this.testObj,
          name: "testObjName",
          methodList: ["test"],
          controller: this.webviewController,
          // 可选参数
          asyncMethodList: [],
          permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
                      '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
                      '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
                      '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
                      '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
      })
    }
}
}
[*] 应用侧使用registerJavaScriptProxy()接口注册。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(): string {
    return "ArkUI Web Component";
}

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

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"],
                  // 可选参数, asyncMethodList
                  [],
                  // 可选参数, permission
                  '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
                  '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
                  '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
                  '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
                  '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
            );
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} 阐明

[*]使用registerJavaScriptProxy()接口注册方法时,注册后需调用refresh()接口生效。
   
[*] 可选参数permission是一个json字符串,示例如下:
{
"javascriptProxyPermission": {
    "urlPermissionList": [       // Object级权限,如果匹配,所有Method都授权
      {
      "scheme": "resource",    // 精确匹配,不能为空
      "host": "rawfile",       // 精确匹配,不能为空
      "port": "",            // 精确匹配,为空不检查
      "path": ""               // 前缀匹配,为空不检查
      },
      {
      "scheme": "https",       // 精确匹配,不能为空
      "host": "xxx.com",       // 精确匹配,不能为空
      "port": "8080",          // 精确匹配,为空不检查
      "path": "a/b/c"          // 前缀匹配,为空不检查
      }
    ],
    "methodList": [
      {
      "methodName": "test",
      "urlPermissionList": [   // Method级权限
          {
            "scheme": "https",   // 精确匹配,不能为空
            "host": "xxx.com",   // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""         // 前缀匹配,为空不检查
          },
          {
            "scheme": "resource",// 精确匹配,不能为空
            "host": "rawfile",   // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""         // 前缀匹配,为空不检查
          }
      ]
      },
      {
      "methodName": "test11",
      "urlPermissionList": [   // Method级权限
          {
            "scheme": "q",       // 精确匹配,不能为空
            "host": "r",         // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": "t"          // 前缀匹配,为空不检查
          },
          {
            "scheme": "u",       // 精确匹配,不能为空
            "host": "v",         // 精确匹配,不能为空
            "port": "",          // 精确匹配,为空不检查
            "path": ""         // 前缀匹配,为空不检查
          }
      ]
      }
    ]
}
}
[*] index.html前端页面触发应用侧代码。
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button 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('ArkTS Hello World! :' + str);
    }
</script>
</body>
</html>
复杂类型使用方法



[*] 应用侧和前端页面之间转达Array。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(): Array<Number> {
    return
}

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

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      testObjName.toString(testObjName.test());
    }
</script>
</body>
</html>
[*] 应用侧和前端页面之间转达基础类型,非Function等复杂类型。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class student {
name: string = '';
age: string = '';
}

class testClass {
constructor() {
}

// 传递的基础类型name:"jeck", age:"12"。
test(): student {
    let st: student = { name: "jeck", age: "12" };
    return st;
}

toString(param: ESObject): void {
    console.log('Web Component toString' + param["name"]);
}
}

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      testObjName.toString(testObjName.test());
    }
</script>
</body>
</html>
[*] 应用侧调用前端页面的Callback。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(param: Function): void {
    param("call callback");
}

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

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      testObjName.test(function(param){testObjName.toString(param)});
    }
</script>
</body>
</html>
[*] 应用侧调用前端页面Object里的Function。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(param: ESObject): void {
    param.hello("call obj func");
}

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

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    // 写法1
    class Student {
      constructor(nameList) {
            this.methodNameListForJsProxy = nameList;
      }
      hello(param) {
            testObjName.toString(param)
      }
    }
    var st = new Student(["hello"])
    // 写法2
    //创建一个构造器,构造函数首字母大写
    function Obj1(){
      this.methodNameListForJsProxy=["hello"];
      this.hello=function(param){
            testObjName.toString(param)
      };
    }
    //利用构造器,通过new关键字生成对象
    var st1 = new Obj1();
    function callArkTS() {
      testObjName.test(st);
      testObjName.test(st1);
    }
</script>
</body>
</html>
[*] 前端页面调用应用侧Object里的Function。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class ObjOther {
methodNameListForJsProxy: string[]

constructor(list: string[]) {
    this.methodNameListForJsProxy = list
}

testOther(json: string): void {
    console.info(json)
}
}

class testClass {
ObjReturn: ObjOther

constructor() {
    this.ObjReturn = new ObjOther(["testOther"]);
}

test(): ESObject {
    return this.ObjReturn
}

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

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      testObjName.test().testOther("call other object func");
    }
</script>
</body>
</html>
[*] Promise场景。
第一种使用方法,在应用侧new Promise。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(): Promise<string> {
    let p: Promise<string> = new Promise((resolve, reject) => {
      setTimeout(() => {
      console.log('执行完成');
      reject('fail');
      }, 10000);
    });
    return p;
}

toString(param: String): void {
    console.log(" " + param);
}
}

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
    Column() {
      Button('refresh')
      .onClick(() => {
          try {
            this.webviewController.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Button('Register JavaScript To Window')
      .onClick(() => {
          try {
            this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},Message: ${(error as BusinessError).message}`);
          }
      })
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
    }
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)})
    }
</script>
</body>
</html> 第二种使用方法,在前端页面new Promise。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class testClass {
constructor() {
}

test(param:Function): void {
setTimeout( () => { param("suc") }, 10000)
}

toString(param:String): void {
console.log(" " + param);
}
}

@Entry
@Component
struct Index {
webviewController: webview.WebviewController = new webview.WebviewController();
@State testObj: testClass = new testClass();

build() {
Column() {
Button('refresh')
.onClick(() => {
try {
this.webviewController.refresh();
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Button('Register JavaScript To Window')
.onClick(() => {
try {
this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: $rawfile('index.html'), controller: this.webviewController })
}
}
} <!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
    function callArkTS() {
      let funpromise
      var p = new Promise(function(resolve, reject){funpromise=(param)=>{resolve(param)}})
      testObjName.test(funpromise)
      p.then((param)=>{testObjName.toString(param)})
    }
</script>
</body>
</html>
https://i-blog.csdnimg.cn/direct/5be73c96555f4ad39cb84daabe28288e.png​

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙NEXT版实战开发:前端页面调用应用侧函数(前端页面JavaScript)