写点什么

鸿蒙网络编程系列 24-Web 组件与应用互操作示例

作者:长弓三石
  • 2024-10-22
    广东
  • 本文字数:4768 字

    阅读完需:约 16 分钟

1. APP 内嵌网页与应用互操作概述

在通常的 APP 开发中,经常会采用内嵌网页的形式,通过网页来展现丰富的动态内容,虽少了很多原生开发的功能,但是这么做无可厚非,毕竟 APP 需要适配的系统平台很多,比如安卓、苹果、各种 PC 端,现在还有如日中天的鸿蒙系统;为每一种平台做定制难度还是很大的,但是这些平台的 APP 都支持内嵌网页,通过网页可以屏蔽各平台的差异,从而减少开发难度,提高开发效率。


当然,单纯的内嵌网页还是有不少局限性的,不过,可以通过应用和网页的互操作来提升用户的使用体验,所谓的互操作,就是可以在网页中调用 APP 中的方法,或者在 APP 中执行网页中的脚本,鸿蒙通过 web 组件中的 javaScriptProxy 接口提供了注册应用侧 js 对象到 web 组件中的方法:


javaScriptProxy(javaScriptProxy: { object: object, name: string, methodList: Array<string>,controller: WebviewController | WebController, asyncMethodList?: Array<string>})
复制代码


当然,也可以使用 WebviewController 的 registerJavaScriptProxy 接口:


registerJavaScriptProxy(object: object, name: string, methodList: Array<string>, asyncMethodList?: Array<string>): void
复制代码


在应用侧执行网页中的脚本使用的是 WebviewController 类的 runJavaScript 接口:


runJavaScript(script: string): Promise<string>
复制代码


通过上述几个接口,就可以实现强大的 Web 组件与应用互操作功能

2. Web 组件与应用互操作示例

本示例运行后的界面如下所示



单击网页中“计算应用侧的乘法”按钮,可以自动计算 app 上部的乘法,计算后的界面如下所示;



在 app 内调节 RGB 颜色分量,设置好选择的背景色后,单击应用中的“设置网页背景色”按钮,可以设置网页的背景色:



下面详细介绍创建该应用的步骤。


步骤 1:创建 Empty Ability 项目。


步骤 2:在 module.json5 配置文件加上对权限的声明:


"requestPermissions": [      {        "name": "ohos.permission.INTERNET"      }    ]
复制代码


这里添加了获取互联网信息的权限。


步骤 3:添加资源文件 demo.html,路径为 src/main/resources/rawfile/demo.html,内容如下:


<!-- index.html --><!DOCTYPE html><html><meta charset="utf-8">
<body> <div style="text-align: center;font-size: larger;"> <button type="button" onclick="compute()">计算应用侧的乘法</button> </div> <div id="info">
</div></body><script type="text/javascript"> function compute() { let multiplier = multipObj.getMultiplier(); let multiplicand = multipObj.getMultiplicand(); let product = multiplier * multiplicand multipObj.setProduct(product); }
function setbackcolor(color) { document.body.style.backgroundColor = color; }</script>
</html>
复制代码


该资源文件很重要,是本示例互操作实现的基础。


步骤 4:在 Index.ets 文件里添加如下的代码:


import web_webview from '@ohos.web.webview'
//注册到web组件中的应用侧js对象class ComputeObj { constructor() { }
public multiplier: number = 0.618 public multiplicand: number = 3.14 public product: string = "乘积"
//获取乘数 public getMultiplier() { return this.multiplier; }
//获取被乘数 public getMultiplicand() { return this.multiplicand; }
//设置乘积 public setProduct(newProduct: number) { this.product = newProduct.toString(); }}
@Entry@Componentstruct Index { @State computeObj: ComputeObj = new ComputeObj() jsName: string = "multipObj" @State rColor: number = 100 @State gColor: number = 100 @State bColor: number = 100 @State backColor: string = "#646464" scroller: Scroller = new Scroller() controller: web_webview.WebviewController = new web_webview.WebviewController()
build() { Row() { Column() { Text("Web组件与应用互操作示例") .fontSize(14) .fontWeight(FontWeight.Bold) .width('100%') .textAlign(TextAlign.Center) .padding(5)
Text("输入乘数和被乘数,在web组件中单击计算按钮进行计算") .fontSize(14) .width('100%') .textAlign(TextAlign.Start) .padding(5)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { TextInput({ text: this.computeObj.multiplier.toString() }) .onChange((value) => { this.computeObj.multiplier = parseFloat(value) }) .type(InputType.NUMBER_DECIMAL) .width(110) .fontSize(11) .flexGrow(1)
Text("*") .fontSize(14) .width(20) .flexGrow(0)
TextInput({ text: this.computeObj.multiplicand.toString() }) .onChange((value) => { this.computeObj.multiplicand = parseFloat(value) }) .type(InputType.NUMBER_DECIMAL) .width(100) .fontSize(11) .flexGrow(1)
Text("=") .fontSize(14) .width(20) .flexGrow(0)
TextInput({ text: `${this.computeObj.product}` }) .width(100) .fontSize(11) .enabled(false) .flexGrow(1) } .width('100%') .padding(5)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text("R颜色分量") .fontSize(14) .width(100) .flexGrow(0)
Slider({ value: this.rColor, min: 0, max: 255 }) .onChange((value: number, mode: SliderChangeMode) => { this.rColor = value this.computeBackcolor() }) .flexGrow(1) } .width('100%') .padding(5)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text("G颜色分量") .fontSize(14) .width(100) .flexGrow(0)
Slider({ value: this.gColor, min: 0, max: 255 }) .onChange((value: number, mode: SliderChangeMode) => { this.gColor = value this.computeBackcolor() }) .flexGrow(1) } .width('100%') .padding(5)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text("B颜色分量") .fontSize(14) .width(100) .flexGrow(0)
Slider({ value: this.bColor, min: 0, max: 255 }) .onChange((value: number, mode: SliderChangeMode) => { this.bColor = value this.computeBackcolor() }) .flexGrow(1) } .width('100%') .padding(5)
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { Text(`选中的颜色:${this.backColor}`) .fontSize(14) .height(30) .width(150) .backgroundColor(this.backColor)
Button("设置网页背景色") .onClick(() => { this.controller.runJavaScript(`setbackcolor('${this.backColor}')`) }) .width(140) .fontSize(14) .flexGrow(0) } .width('100%') .padding(5)
Scroll(this.scroller) { Web({ src: $rawfile("demo.html"), controller: this.controller }) .padding(10) .width('100%') .textZoomRatio(300) .backgroundColor(0xeeeeee) //注册js对象 .javaScriptProxy({ object: this.computeObj, name: this.jsName, methodList: ["getMultiplier", "getMultiplicand", "setProduct"], controller: this.controller, }) } .align(Alignment.Top) .backgroundColor(0xeeeeee) .height(300) .flexGrow(1) .scrollable(ScrollDirection.Vertical) .scrollBar(BarState.On) .scrollBarWidth(20) } .width('100%') .justifyContent(FlexAlign.Start) .height('100%') } .height('100%') }
//计算背景色 computeBackcolor() { this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16) + parseInt(this.gColor.toFixed(0)).toString(16) + parseInt(this.bColor.toFixed(0)).toString(16) }}
复制代码


步骤 5:编译运行,可以使用模拟器或者真机。


步骤 6:具体的操作过程上面讲过了,就不再赘述了。

3. 关键功能分析

第一个是要注册到 web 组件中的 js 对象,在 API12 中写成 class 的形式,


//注册到web组件中的应用侧js对象class ComputeObj {  constructor() {  }
public multiplier: number = 0.618 public multiplicand: number = 3.14 public product: string = "乘积"
//获取乘数 public getMultiplier() { return this.multiplier; }
//获取被乘数 public getMultiplicand() { return this.multiplicand; }
//设置乘积 public setProduct(newProduct: number) { this.product = newProduct.toString(); }}
复制代码


第二个是注册对象的代码:


Web({ src: $rawfile("demo.html"), controller: this.controller })            .padding(10)            .width('100%')            .textZoomRatio(300)            .backgroundColor(0xeeeeee)            //注册js对象            .javaScriptProxy({              object: this.computeObj,              name: this.jsName,              methodList: ["getMultiplier", "getMultiplicand", "setProduct"],              controller: this.controller,            })
复制代码


这里 javaScriptProxy 方法的各个参数一定要保证准确,否则在 web 组件中调用会失败,其中 name 和 demo.html 中使用的注册对象名称 multipObj 要完全一致,methodList 参数为注册对象声明的方法,也要保证拼写正确。


最后是计算背景的代码:


  //计算背景色  computeBackcolor() {    this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16)      + parseInt(this.gColor.toFixed(0)).toString(16)      + parseInt(this.bColor.toFixed(0)).toString(16)  }
复制代码


把选中的颜色分量拼凑成了颜色字符串,最前面的是字符 #。


(本文作者原创,除非明确授权禁止转载)


本文源码地址:


https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/WebAppInteropDemo


本系列源码地址:


https://gitee.com/zl3624/harmonyos_network_samples


发布于: 刚刚阅读数: 4
用户头像

长弓三石

关注

还未添加个人签名 2024-10-16 加入

二十多年软件开发经验的软件架构师,华为HDE、华为云HCDE、仓颉语言CLD、CCS,著有《仓颉语言网络编程》、《仓颉语言元编程》、《仓颉语言实战》、《鲲鹏架构入门与实战》等书籍,清华大学出版社出版。

评论

发布
暂无评论
鸿蒙网络编程系列24-Web组件与应用互操作示例_DevEco Studio_长弓三石_InfoQ写作社区