HarmonyOS NEXT鸿蒙(开发进阶)Web组件与APP应用互操作实践 ...

打印 上一主题 下一主题

主题 965|帖子 965|积分 2895

  鸿蒙NEXT开发实战往期必看文章:
一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!
“非常具体的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到夺目)
HarmonyOS NEXT应用开发案例实践总结合(连续更新......)
HarmonyOS NEXT应用开发性能优化实践总结(连续更新......)

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

在通常的APP开发中,经常会采用内嵌网页的形式,通过网页来展现丰富的动态内容,虽少了很多原生开发的功能,但是这么做无可厚非,究竟APP需要适配的系统平台很多,好比安卓、苹果、各种PC端,如今另有方兴未艾的鸿蒙系统;为每一种平台做定制难度还是很大的,但是这些平台的APP都支持内嵌网页,通过网页可以屏蔽各平台的差异,从而减少开发难度,提高开发服从。
当然,单纯的内嵌网页还是有不少局限性的,不过,可以通过应用和网页的互操作来提升用户的使用体验,所谓的互操作,就是可以在网页中调用APP中的方法,或者在APP中执行网页中的脚本,鸿蒙通过web组件中的javaScriptProxy接口提供了注册应用侧js对象到web组件中的方法:
  1. javaScriptProxy(javaScriptProxy: { object: object, name: string, methodList: Array<string>,controller: WebviewController | WebController, asyncMethodList?: Array<string>})
复制代码
当然,也可以使用WebviewController的registerJavaScriptProxy接口:
  1. registerJavaScriptProxy(object: object, name: string, methodList: Array<string>, asyncMethodList?: Array<string>): void
复制代码
在应用侧执行网页中的脚本使用的是WebviewController类的runJavaScript接口:
  1. runJavaScript(script: string): Promise<string>
复制代码
通过上述几个接口,就可以实现强盛的Web组件与应用互操作功能
2. Web组件与应用互操作示例

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


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


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


下面具体介绍创建该应用的步调。
步调1:创建Empty Ability项目。
步调2:在module.json5配置文件加上对权限的声明:
  1. "requestPermissions": [
  2.       {
  3.         "name": "ohos.permission.INTERNET"
  4.       }
  5.     ]
复制代码
这里添加了获取互联网信息的权限。
步调3:添加资源文件demo.html,路径为src/main/resources/rawfile/demo.html,内容如下:
  1. <!-- index.html -->
  2. <!DOCTYPE html>
  3. <html>
  4. <meta charset="utf-8">
  5. <body>
  6.   <div style="text-align: center;font-size: larger;">
  7.     <button type="button" onclick="compute()">计算应用侧的乘法</button>
  8.   </div>
  9.   <div id="info">
  10.   </div>
  11. </body>
  12. <script type="text/javascript">
  13.   function compute() {
  14.     let multiplier = multipObj.getMultiplier();
  15.     let multiplicand = multipObj.getMultiplicand();
  16.     let product = multiplier * multiplicand
  17.     multipObj.setProduct(product);
  18.   }
  19.   function setbackcolor(color) {
  20.     document.body.style.backgroundColor = color;
  21.   }
  22. </script>
  23. </html>
复制代码
该资源文件很告急,是本示例互操作实现的基础。
步调4:在Index.ets文件里添加如下的代码:
  1. import web_webview from '@ohos.web.webview'
  2. //注册到web组件中的应用侧js对象
  3. class ComputeObj {
  4.   constructor() {
  5.   }
  6.   public multiplier: number = 0.618
  7.   public multiplicand: number = 3.14
  8.   public product: string = "乘积"
  9.   //获取乘数
  10.   public getMultiplier() {
  11.     return this.multiplier;
  12.   }
  13.   //获取被乘数
  14.   public getMultiplicand() {
  15.     return this.multiplicand;
  16.   }
  17.   //设置乘积
  18.   public setProduct(newProduct: number) {
  19.     this.product = newProduct.toString();
  20.   }
  21. }
  22. @Entry
  23. @Component
  24. struct Index {
  25.   @State computeObj: ComputeObj = new ComputeObj()
  26.   jsName: string = "multipObj"
  27.   @State rColor: number = 100
  28.   @State gColor: number = 100
  29.   @State bColor: number = 100
  30.   @State backColor: string = "#646464"
  31.   scroller: Scroller = new Scroller()
  32.   controller: web_webview.WebviewController = new web_webview.WebviewController()
  33.   build() {
  34.     Row() {
  35.       Column() {
  36.         Text("Web组件与应用互操作示例")
  37.           .fontSize(14)
  38.           .fontWeight(FontWeight.Bold)
  39.           .width('100%')
  40.           .textAlign(TextAlign.Center)
  41.           .padding(5)
  42.         Text("输入乘数和被乘数,在web组件中单击计算按钮进行计算")
  43.           .fontSize(14)
  44.           .width('100%')
  45.           .textAlign(TextAlign.Start)
  46.           .padding(5)
  47.         Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
  48.           TextInput({ text: this.computeObj.multiplier.toString() })
  49.             .onChange((value) => {
  50.               this.computeObj.multiplier = parseFloat(value)
  51.             })
  52.             .type(InputType.NUMBER_DECIMAL)
  53.             .width(110)
  54.             .fontSize(11)
  55.             .flexGrow(1)
  56.           Text("*")
  57.             .fontSize(14)
  58.             .width(20)
  59.             .flexGrow(0)
  60.           TextInput({ text: this.computeObj.multiplicand.toString() })
  61.             .onChange((value) => {
  62.               this.computeObj.multiplicand = parseFloat(value)
  63.             })
  64.             .type(InputType.NUMBER_DECIMAL)
  65.             .width(100)
  66.             .fontSize(11)
  67.             .flexGrow(1)
  68.           Text("=")
  69.             .fontSize(14)
  70.             .width(20)
  71.             .flexGrow(0)
  72.           TextInput({ text: `${this.computeObj.product}` })
  73.             .width(100)
  74.             .fontSize(11)
  75.             .enabled(false)
  76.             .flexGrow(1)
  77.         }
  78.         .width('100%')
  79.         .padding(5)
  80.         Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
  81.           Text("R颜色分量")
  82.             .fontSize(14)
  83.             .width(100)
  84.             .flexGrow(0)
  85.           Slider({ value: this.rColor, min: 0, max: 255 })
  86.             .onChange((value: number, mode: SliderChangeMode) => {
  87.               this.rColor = value
  88.               this.computeBackcolor()
  89.             })
  90.             .flexGrow(1)
  91.         }
  92.         .width('100%')
  93.         .padding(5)
  94.         Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
  95.           Text("G颜色分量")
  96.             .fontSize(14)
  97.             .width(100)
  98.             .flexGrow(0)
  99.           Slider({ value: this.gColor, min: 0, max: 255 })
  100.             .onChange((value: number, mode: SliderChangeMode) => {
  101.               this.gColor = value
  102.               this.computeBackcolor()
  103.             })
  104.             .flexGrow(1)
  105.         }
  106.         .width('100%')
  107.         .padding(5)
  108.         Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
  109.           Text("B颜色分量")
  110.             .fontSize(14)
  111.             .width(100)
  112.             .flexGrow(0)
  113.           Slider({ value: this.bColor, min: 0, max: 255 })
  114.             .onChange((value: number, mode: SliderChangeMode) => {
  115.               this.bColor = value
  116.               this.computeBackcolor()
  117.             })
  118.             .flexGrow(1)
  119.         }
  120.         .width('100%')
  121.         .padding(5)
  122.         Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
  123.           Text(`选中的颜色:${this.backColor}`)
  124.             .fontSize(14)
  125.             .height(30)
  126.             .width(150)
  127.             .backgroundColor(this.backColor)
  128.           Button("设置网页背景色")
  129.             .onClick(() => {
  130.               this.controller.runJavaScript(`setbackcolor('${this.backColor}')`)
  131.             })
  132.             .width(140)
  133.             .fontSize(14)
  134.             .flexGrow(0)
  135.         }
  136.         .width('100%')
  137.         .padding(5)
  138.         Scroll(this.scroller) {
  139.           Web({ src: $rawfile("demo.html"), controller: this.controller })
  140.             .padding(10)
  141.             .width('100%')
  142.             .textZoomRatio(300)
  143.             .backgroundColor(0xeeeeee)
  144.             //注册js对象
  145.             .javaScriptProxy({
  146.               object: this.computeObj,
  147.               name: this.jsName,
  148.               methodList: ["getMultiplier", "getMultiplicand", "setProduct"],
  149.               controller: this.controller,
  150.             })
  151.         }
  152.         .align(Alignment.Top)
  153.         .backgroundColor(0xeeeeee)
  154.         .height(300)
  155.         .flexGrow(1)
  156.         .scrollable(ScrollDirection.Vertical)
  157.         .scrollBar(BarState.On)
  158.         .scrollBarWidth(20)
  159.       }
  160.       .width('100%')
  161.       .justifyContent(FlexAlign.Start)
  162.       .height('100%')
  163.     }
  164.     .height('100%')
  165.   }
  166.   //计算背景色
  167.   computeBackcolor() {
  168.     this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16)
  169.       + parseInt(this.gColor.toFixed(0)).toString(16)
  170.       + parseInt(this.bColor.toFixed(0)).toString(16)
  171.   }
  172. }
复制代码
步调5:编译运行,可以使用模仿器或者真机。
步调6:具体的操作过程上面讲过了,就不再赘述了。
3. 关键功能分析

第一个是要注册到web组件中的js对象,在API12中写成class的形式,
  1. //注册到web组件中的应用侧js对象
  2. class ComputeObj {
  3.   constructor() {
  4.   }
  5.   public multiplier: number = 0.618
  6.   public multiplicand: number = 3.14
  7.   public product: string = "乘积"
  8.   //获取乘数
  9.   public getMultiplier() {
  10.     return this.multiplier;
  11.   }
  12.   //获取被乘数
  13.   public getMultiplicand() {
  14.     return this.multiplicand;
  15.   }
  16.   //设置乘积
  17.   public setProduct(newProduct: number) {
  18.     this.product = newProduct.toString();
  19.   }
  20. }
复制代码
第二个是注册对象的代码:
  1. Web({ src: $rawfile("demo.html"), controller: this.controller })
  2.             .padding(10)
  3.             .width('100%')
  4.             .textZoomRatio(300)
  5.             .backgroundColor(0xeeeeee)
  6.             //注册js对象
  7.             .javaScriptProxy({
  8.               object: this.computeObj,
  9.               name: this.jsName,
  10.               methodList: ["getMultiplier", "getMultiplicand", "setProduct"],
  11.               controller: this.controller,
  12.             })
复制代码
这里javaScriptProxy方法的各个参数肯定要包管正确,否则在web组件中调用会失败,其中name和demo.html中使用的注册对象名称multipObj要完全一致,methodList参数为注册对象声明的方法,也要包管拼写正确。
最后是盘算背景的代码:
  1.   //计算背景色
  2.   computeBackcolor() {
  3.     this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16)
  4.       + parseInt(this.gColor.toFixed(0)).toString(16)
  5.       + parseInt(this.bColor.toFixed(0)).toString(16)
  6.   }
复制代码
把选中的颜色分量拼集成了颜色字符串,最前面的是字符#。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表